Internship
json.hpp
Go to the documentation of this file.
1// __ _____ _____ _____
2// __| | __| | | | JSON for Modern C++
3// | | |__ | | | | | | version 3.11.1
4// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9/****************************************************************************\
10 * Note on documentation: The source files contain links to the online *
11 * documentation of the public API at https://json.nlohmann.me. This URL *
12 * contains the most recent documentation and should also be applicable to *
13 * previous versions; documentation for deprecated functions is not *
14 * removed, but marked deprecated. See "Generate documentation" section in *
15 * file docs/README.md. *
16\****************************************************************************/
17
18#ifndef INCLUDE_NLOHMANN_JSON_HPP_
19#define INCLUDE_NLOHMANN_JSON_HPP_
20
21#include <algorithm> // all_of, find, for_each
22#include <cstddef> // nullptr_t, ptrdiff_t, size_t
23#include <functional> // hash, less
24#include <initializer_list> // initializer_list
25#ifndef JSON_NO_IO
26 #include <iosfwd> // istream, ostream
27#endif // JSON_NO_IO
28#include <iterator> // random_access_iterator_tag
29#include <memory> // unique_ptr
30#include <numeric> // accumulate
31#include <string> // string, stoi, to_string
32#include <utility> // declval, forward, move, pair, swap
33#include <vector> // vector
34
35// #include <nlohmann/adl_serializer.hpp>
36// __ _____ _____ _____
37// __| | __| | | | JSON for Modern C++
38// | | |__ | | | | | | version 3.11.1
39// |_____|_____|_____|_|___| https://github.com/nlohmann/json
40//
41// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
42// SPDX-License-Identifier: MIT
43
44
45
46#include <utility>
47
48// #include <nlohmann/detail/abi_macros.hpp>
49// __ _____ _____ _____
50// __| | __| | | | JSON for Modern C++
51// | | |__ | | | | | | version 3.11.1
52// |_____|_____|_____|_|___| https://github.com/nlohmann/json
53//
54// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
55// SPDX-License-Identifier: MIT
56
57
58
59// This file contains all macro definitions affecting or depending on the ABI
60
61#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
62 #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
63 #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 1
64 #warning "Already included a different version of the library!"
65 #endif
66 #endif
67#endif
68
69#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
70#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)
71#define NLOHMANN_JSON_VERSION_PATCH 1 // NOLINT(modernize-macro-to-enum)
72
73#ifndef JSON_DIAGNOSTICS
74 #define JSON_DIAGNOSTICS 0
75#endif
76
77#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
78 #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
79#endif
80
81#if JSON_DIAGNOSTICS
82 #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
83#else
84 #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
85#endif
86
87#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
88 #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
89#else
90 #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
91#endif
92
93#define NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch) \
94 json_v ## major ## _ ## minor ## _ ## patch
95#define NLOHMANN_JSON_ABI_PREFIX(major, minor, patch) \
96 NLOHMANN_JSON_ABI_PREFIX_EX(major, minor, patch)
97
98#define NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c) a ## b ## c
99#define NLOHMANN_JSON_ABI_CONCAT(a, b, c) \
100 NLOHMANN_JSON_ABI_CONCAT_EX(a, b, c)
101
102#define NLOHMANN_JSON_ABI_STRING \
103 NLOHMANN_JSON_ABI_CONCAT( \
104 NLOHMANN_JSON_ABI_PREFIX( \
105 NLOHMANN_JSON_VERSION_MAJOR, \
106 NLOHMANN_JSON_VERSION_MINOR, \
107 NLOHMANN_JSON_VERSION_PATCH), \
108 NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
109 NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
110
111#ifndef NLOHMANN_JSON_NAMESPACE
112 #define NLOHMANN_JSON_NAMESPACE nlohmann::NLOHMANN_JSON_ABI_STRING
113#endif
114
115#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
116#define NLOHMANN_JSON_NAMESPACE_BEGIN \
117 namespace nlohmann \
118 { \
119 inline namespace NLOHMANN_JSON_ABI_STRING \
120 {
121#endif
122
123#ifndef NLOHMANN_JSON_NAMESPACE_END
124#define NLOHMANN_JSON_NAMESPACE_END \
125 } /* namespace (abi_string) */ \
126 } /* namespace nlohmann */
127#endif
128
129// #include <nlohmann/detail/conversions/from_json.hpp>
130// __ _____ _____ _____
131// __| | __| | | | JSON for Modern C++
132// | | |__ | | | | | | version 3.11.1
133// |_____|_____|_____|_|___| https://github.com/nlohmann/json
134//
135// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
136// SPDX-License-Identifier: MIT
137
138
139
140#include <algorithm> // transform
141#include <array> // array
142#include <forward_list> // forward_list
143#include <iterator> // inserter, front_inserter, end
144#include <map> // map
145#include <string> // string
146#include <tuple> // tuple, make_tuple
147#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
148#include <unordered_map> // unordered_map
149#include <utility> // pair, declval
150#include <valarray> // valarray
151
152// #include <nlohmann/detail/exceptions.hpp>
153// __ _____ _____ _____
154// __| | __| | | | JSON for Modern C++
155// | | |__ | | | | | | version 3.11.1
156// |_____|_____|_____|_|___| https://github.com/nlohmann/json
157//
158// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
159// SPDX-License-Identifier: MIT
160
161
162
163#include <cstddef> // nullptr_t
164#include <exception> // exception
165#include <stdexcept> // runtime_error
166#include <string> // to_string
167#include <vector> // vector
168
169// #include <nlohmann/detail/value_t.hpp>
170// __ _____ _____ _____
171// __| | __| | | | JSON for Modern C++
172// | | |__ | | | | | | version 3.11.1
173// |_____|_____|_____|_|___| https://github.com/nlohmann/json
174//
175// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
176// SPDX-License-Identifier: MIT
177
178
179
180#include <array> // array
181#include <cstddef> // size_t
182#include <cstdint> // uint8_t
183#include <string> // string
184
185// #include <nlohmann/detail/macro_scope.hpp>
186// __ _____ _____ _____
187// __| | __| | | | JSON for Modern C++
188// | | |__ | | | | | | version 3.11.1
189// |_____|_____|_____|_|___| https://github.com/nlohmann/json
190//
191// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
192// SPDX-License-Identifier: MIT
193
194
195
196#include <utility> // declval, pair
197// #include <nlohmann/detail/meta/detected.hpp>
198// __ _____ _____ _____
199// __| | __| | | | JSON for Modern C++
200// | | |__ | | | | | | version 3.11.1
201// |_____|_____|_____|_|___| https://github.com/nlohmann/json
202//
203// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
204// SPDX-License-Identifier: MIT
205
206
207
208#include <type_traits>
209
210// #include <nlohmann/detail/meta/void_t.hpp>
211// __ _____ _____ _____
212// __| | __| | | | JSON for Modern C++
213// | | |__ | | | | | | version 3.11.1
214// |_____|_____|_____|_|___| https://github.com/nlohmann/json
215//
216// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
217// SPDX-License-Identifier: MIT
218
219
220
221// #include <nlohmann/detail/abi_macros.hpp>
222
223
225namespace detail
226{
227
228template<typename ...Ts> struct make_void
229{
230 using type = void;
231};
232template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
233
234} // namespace detail
236
237
239namespace detail
240{
241
242// https://en.cppreference.com/w/cpp/experimental/is_detected
244{
245 nonesuch() = delete;
246 ~nonesuch() = delete;
247 nonesuch(nonesuch const&) = delete;
248 nonesuch(nonesuch const&&) = delete;
249 void operator=(nonesuch const&) = delete;
250 void operator=(nonesuch&&) = delete;
251};
252
253template<class Default,
254 class AlwaysVoid,
255 template<class...> class Op,
256 class... Args>
258{
259 using value_t = std::false_type;
260 using type = Default;
261};
262
263template<class Default, template<class...> class Op, class... Args>
264struct detector<Default, void_t<Op<Args...>>, Op, Args...>
265{
266 using value_t = std::true_type;
267 using type = Op<Args...>;
268};
269
270template<template<class...> class Op, class... Args>
271using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
272
273template<template<class...> class Op, class... Args>
274struct is_detected_lazy : is_detected<Op, Args...> { };
275
276template<template<class...> class Op, class... Args>
277using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
278
279template<class Default, template<class...> class Op, class... Args>
280using detected_or = detector<Default, void, Op, Args...>;
281
282template<class Default, template<class...> class Op, class... Args>
283using detected_or_t = typename detected_or<Default, Op, Args...>::type;
284
285template<class Expected, template<class...> class Op, class... Args>
286using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
287
288template<class To, template<class...> class Op, class... Args>
290 std::is_convertible<detected_t<Op, Args...>, To>;
291
292} // namespace detail
294
295// #include <nlohmann/thirdparty/hedley/hedley.hpp>
296
297
298// __ _____ _____ _____
299// __| | __| | | | JSON for Modern C++
300// | | |__ | | | | | | version 3.11.1
301// |_____|_____|_____|_|___| https://github.com/nlohmann/json
302//
303// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
304// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
305// SPDX-License-Identifier: MIT
306
307/* Hedley - https://nemequ.github.io/hedley
308 * Created by Evan Nemerson <evan@nemerson.com>
309 */
310
311#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
312#if defined(JSON_HEDLEY_VERSION)
313 #undef JSON_HEDLEY_VERSION
314#endif
315#define JSON_HEDLEY_VERSION 15
316
317#if defined(JSON_HEDLEY_STRINGIFY_EX)
318 #undef JSON_HEDLEY_STRINGIFY_EX
319#endif
320#define JSON_HEDLEY_STRINGIFY_EX(x) #x
321
322#if defined(JSON_HEDLEY_STRINGIFY)
323 #undef JSON_HEDLEY_STRINGIFY
324#endif
325#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
326
327#if defined(JSON_HEDLEY_CONCAT_EX)
328 #undef JSON_HEDLEY_CONCAT_EX
329#endif
330#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
331
332#if defined(JSON_HEDLEY_CONCAT)
333 #undef JSON_HEDLEY_CONCAT
334#endif
335#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
336
337#if defined(JSON_HEDLEY_CONCAT3_EX)
338 #undef JSON_HEDLEY_CONCAT3_EX
339#endif
340#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
341
342#if defined(JSON_HEDLEY_CONCAT3)
343 #undef JSON_HEDLEY_CONCAT3
344#endif
345#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
346
347#if defined(JSON_HEDLEY_VERSION_ENCODE)
348 #undef JSON_HEDLEY_VERSION_ENCODE
349#endif
350#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
351
352#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
353 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
354#endif
355#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
356
357#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
358 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
359#endif
360#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
361
362#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
363 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
364#endif
365#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
366
367#if defined(JSON_HEDLEY_GNUC_VERSION)
368 #undef JSON_HEDLEY_GNUC_VERSION
369#endif
370#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
371 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
372#elif defined(__GNUC__)
373 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
374#endif
375
376#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
377 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
378#endif
379#if defined(JSON_HEDLEY_GNUC_VERSION)
380 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
381#else
382 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
383#endif
384
385#if defined(JSON_HEDLEY_MSVC_VERSION)
386 #undef JSON_HEDLEY_MSVC_VERSION
387#endif
388#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
389 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
390#elif defined(_MSC_FULL_VER) && !defined(__ICL)
391 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
392#elif defined(_MSC_VER) && !defined(__ICL)
393 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
394#endif
395
396#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
397 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
398#endif
399#if !defined(JSON_HEDLEY_MSVC_VERSION)
400 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
401#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
402 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
403#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
404 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
405#else
406 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
407#endif
408
409#if defined(JSON_HEDLEY_INTEL_VERSION)
410 #undef JSON_HEDLEY_INTEL_VERSION
411#endif
412#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
413 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
414#elif defined(__INTEL_COMPILER) && !defined(__ICL)
415 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
416#endif
417
418#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
419 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
420#endif
421#if defined(JSON_HEDLEY_INTEL_VERSION)
422 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
423#else
424 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
425#endif
426
427#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
428 #undef JSON_HEDLEY_INTEL_CL_VERSION
429#endif
430#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
431 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
432#endif
433
434#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
435 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
436#endif
437#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
438 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
439#else
440 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
441#endif
442
443#if defined(JSON_HEDLEY_PGI_VERSION)
444 #undef JSON_HEDLEY_PGI_VERSION
445#endif
446#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
447 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
448#endif
449
450#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
451 #undef JSON_HEDLEY_PGI_VERSION_CHECK
452#endif
453#if defined(JSON_HEDLEY_PGI_VERSION)
454 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
455#else
456 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
457#endif
458
459#if defined(JSON_HEDLEY_SUNPRO_VERSION)
460 #undef JSON_HEDLEY_SUNPRO_VERSION
461#endif
462#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
463 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
464#elif defined(__SUNPRO_C)
465 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
466#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
467 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
468#elif defined(__SUNPRO_CC)
469 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
470#endif
471
472#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
473 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
474#endif
475#if defined(JSON_HEDLEY_SUNPRO_VERSION)
476 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
477#else
478 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
479#endif
480
481#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
482 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
483#endif
484#if defined(__EMSCRIPTEN__)
485 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
486#endif
487
488#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
489 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
490#endif
491#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
492 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
493#else
494 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
495#endif
496
497#if defined(JSON_HEDLEY_ARM_VERSION)
498 #undef JSON_HEDLEY_ARM_VERSION
499#endif
500#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
501 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
502#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
503 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
504#endif
505
506#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
507 #undef JSON_HEDLEY_ARM_VERSION_CHECK
508#endif
509#if defined(JSON_HEDLEY_ARM_VERSION)
510 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
511#else
512 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
513#endif
514
515#if defined(JSON_HEDLEY_IBM_VERSION)
516 #undef JSON_HEDLEY_IBM_VERSION
517#endif
518#if defined(__ibmxl__)
519 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
520#elif defined(__xlC__) && defined(__xlC_ver__)
521 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
522#elif defined(__xlC__)
523 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
524#endif
525
526#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
527 #undef JSON_HEDLEY_IBM_VERSION_CHECK
528#endif
529#if defined(JSON_HEDLEY_IBM_VERSION)
530 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
531#else
532 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
533#endif
534
535#if defined(JSON_HEDLEY_TI_VERSION)
536 #undef JSON_HEDLEY_TI_VERSION
537#endif
538#if \
539 defined(__TI_COMPILER_VERSION__) && \
540 ( \
541 defined(__TMS470__) || defined(__TI_ARM__) || \
542 defined(__MSP430__) || \
543 defined(__TMS320C2000__) \
544 )
545#if (__TI_COMPILER_VERSION__ >= 16000000)
546 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
547#endif
548#endif
549
550#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
551 #undef JSON_HEDLEY_TI_VERSION_CHECK
552#endif
553#if defined(JSON_HEDLEY_TI_VERSION)
554 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
555#else
556 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
557#endif
558
559#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
560 #undef JSON_HEDLEY_TI_CL2000_VERSION
561#endif
562#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
563 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
564#endif
565
566#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
567 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
568#endif
569#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
570 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
571#else
572 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
573#endif
574
575#if defined(JSON_HEDLEY_TI_CL430_VERSION)
576 #undef JSON_HEDLEY_TI_CL430_VERSION
577#endif
578#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
579 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
580#endif
581
582#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
583 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
584#endif
585#if defined(JSON_HEDLEY_TI_CL430_VERSION)
586 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
587#else
588 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
589#endif
590
591#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
592 #undef JSON_HEDLEY_TI_ARMCL_VERSION
593#endif
594#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
595 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
596#endif
597
598#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
599 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
600#endif
601#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
602 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
603#else
604 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
605#endif
606
607#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
608 #undef JSON_HEDLEY_TI_CL6X_VERSION
609#endif
610#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
611 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
612#endif
613
614#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
615 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
616#endif
617#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
618 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
619#else
620 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
621#endif
622
623#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
624 #undef JSON_HEDLEY_TI_CL7X_VERSION
625#endif
626#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
627 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
628#endif
629
630#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
631 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
632#endif
633#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
634 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
635#else
636 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
637#endif
638
639#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
640 #undef JSON_HEDLEY_TI_CLPRU_VERSION
641#endif
642#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
643 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
644#endif
645
646#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
647 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
648#endif
649#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
650 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
651#else
652 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
653#endif
654
655#if defined(JSON_HEDLEY_CRAY_VERSION)
656 #undef JSON_HEDLEY_CRAY_VERSION
657#endif
658#if defined(_CRAYC)
659 #if defined(_RELEASE_PATCHLEVEL)
660 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
661 #else
662 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
663 #endif
664#endif
665
666#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
667 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
668#endif
669#if defined(JSON_HEDLEY_CRAY_VERSION)
670 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
671#else
672 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
673#endif
674
675#if defined(JSON_HEDLEY_IAR_VERSION)
676 #undef JSON_HEDLEY_IAR_VERSION
677#endif
678#if defined(__IAR_SYSTEMS_ICC__)
679 #if __VER__ > 1000
680 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
681 #else
682 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
683 #endif
684#endif
685
686#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
687 #undef JSON_HEDLEY_IAR_VERSION_CHECK
688#endif
689#if defined(JSON_HEDLEY_IAR_VERSION)
690 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
691#else
692 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
693#endif
694
695#if defined(JSON_HEDLEY_TINYC_VERSION)
696 #undef JSON_HEDLEY_TINYC_VERSION
697#endif
698#if defined(__TINYC__)
699 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
700#endif
701
702#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
703 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
704#endif
705#if defined(JSON_HEDLEY_TINYC_VERSION)
706 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
707#else
708 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
709#endif
710
711#if defined(JSON_HEDLEY_DMC_VERSION)
712 #undef JSON_HEDLEY_DMC_VERSION
713#endif
714#if defined(__DMC__)
715 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
716#endif
717
718#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
719 #undef JSON_HEDLEY_DMC_VERSION_CHECK
720#endif
721#if defined(JSON_HEDLEY_DMC_VERSION)
722 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
723#else
724 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
725#endif
726
727#if defined(JSON_HEDLEY_COMPCERT_VERSION)
728 #undef JSON_HEDLEY_COMPCERT_VERSION
729#endif
730#if defined(__COMPCERT_VERSION__)
731 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
732#endif
733
734#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
735 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
736#endif
737#if defined(JSON_HEDLEY_COMPCERT_VERSION)
738 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
739#else
740 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
741#endif
742
743#if defined(JSON_HEDLEY_PELLES_VERSION)
744 #undef JSON_HEDLEY_PELLES_VERSION
745#endif
746#if defined(__POCC__)
747 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
748#endif
749
750#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
751 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
752#endif
753#if defined(JSON_HEDLEY_PELLES_VERSION)
754 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
755#else
756 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
757#endif
758
759#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
760 #undef JSON_HEDLEY_MCST_LCC_VERSION
761#endif
762#if defined(__LCC__) && defined(__LCC_MINOR__)
763 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
764#endif
765
766#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
767 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
768#endif
769#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
770 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
771#else
772 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
773#endif
774
775#if defined(JSON_HEDLEY_GCC_VERSION)
776 #undef JSON_HEDLEY_GCC_VERSION
777#endif
778#if \
779 defined(JSON_HEDLEY_GNUC_VERSION) && \
780 !defined(__clang__) && \
781 !defined(JSON_HEDLEY_INTEL_VERSION) && \
782 !defined(JSON_HEDLEY_PGI_VERSION) && \
783 !defined(JSON_HEDLEY_ARM_VERSION) && \
784 !defined(JSON_HEDLEY_CRAY_VERSION) && \
785 !defined(JSON_HEDLEY_TI_VERSION) && \
786 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
787 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
788 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
789 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
790 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
791 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
792 !defined(__COMPCERT__) && \
793 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
794 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
795#endif
796
797#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
798 #undef JSON_HEDLEY_GCC_VERSION_CHECK
799#endif
800#if defined(JSON_HEDLEY_GCC_VERSION)
801 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
802#else
803 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
804#endif
805
806#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
807 #undef JSON_HEDLEY_HAS_ATTRIBUTE
808#endif
809#if \
810 defined(__has_attribute) && \
811 ( \
812 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
813 )
814# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
815#else
816# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
817#endif
818
819#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
820 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
821#endif
822#if defined(__has_attribute)
823 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
824#else
825 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
826#endif
827
828#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
829 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
830#endif
831#if defined(__has_attribute)
832 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
833#else
834 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
835#endif
836
837#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
838 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
839#endif
840#if \
841 defined(__has_cpp_attribute) && \
842 defined(__cplusplus) && \
843 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
844 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
845#else
846 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
847#endif
848
849#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
850 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
851#endif
852#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
853 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
854#elif \
855 !defined(JSON_HEDLEY_PGI_VERSION) && \
856 !defined(JSON_HEDLEY_IAR_VERSION) && \
857 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
858 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
859 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
860#else
861 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
862#endif
863
864#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
865 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
866#endif
867#if defined(__has_cpp_attribute) && defined(__cplusplus)
868 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
869#else
870 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
871#endif
872
873#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
874 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
875#endif
876#if defined(__has_cpp_attribute) && defined(__cplusplus)
877 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
878#else
879 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
880#endif
881
882#if defined(JSON_HEDLEY_HAS_BUILTIN)
883 #undef JSON_HEDLEY_HAS_BUILTIN
884#endif
885#if defined(__has_builtin)
886 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
887#else
888 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
889#endif
890
891#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
892 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
893#endif
894#if defined(__has_builtin)
895 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
896#else
897 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
898#endif
899
900#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
901 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
902#endif
903#if defined(__has_builtin)
904 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
905#else
906 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
907#endif
908
909#if defined(JSON_HEDLEY_HAS_FEATURE)
910 #undef JSON_HEDLEY_HAS_FEATURE
911#endif
912#if defined(__has_feature)
913 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
914#else
915 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
916#endif
917
918#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
919 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
920#endif
921#if defined(__has_feature)
922 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
923#else
924 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
925#endif
926
927#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
928 #undef JSON_HEDLEY_GCC_HAS_FEATURE
929#endif
930#if defined(__has_feature)
931 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
932#else
933 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
934#endif
935
936#if defined(JSON_HEDLEY_HAS_EXTENSION)
937 #undef JSON_HEDLEY_HAS_EXTENSION
938#endif
939#if defined(__has_extension)
940 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
941#else
942 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
943#endif
944
945#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
946 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
947#endif
948#if defined(__has_extension)
949 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
950#else
951 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
952#endif
953
954#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
955 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
956#endif
957#if defined(__has_extension)
958 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
959#else
960 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
961#endif
962
963#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
964 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
965#endif
966#if defined(__has_declspec_attribute)
967 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
968#else
969 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
970#endif
971
972#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
973 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
974#endif
975#if defined(__has_declspec_attribute)
976 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
977#else
978 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
979#endif
980
981#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
982 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
983#endif
984#if defined(__has_declspec_attribute)
985 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
986#else
987 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
988#endif
989
990#if defined(JSON_HEDLEY_HAS_WARNING)
991 #undef JSON_HEDLEY_HAS_WARNING
992#endif
993#if defined(__has_warning)
994 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
995#else
996 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
997#endif
998
999#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1000 #undef JSON_HEDLEY_GNUC_HAS_WARNING
1001#endif
1002#if defined(__has_warning)
1003 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1004#else
1005 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1006#endif
1007
1008#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1009 #undef JSON_HEDLEY_GCC_HAS_WARNING
1010#endif
1011#if defined(__has_warning)
1012 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1013#else
1014 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1015#endif
1016
1017#if \
1018 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1019 defined(__clang__) || \
1020 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1021 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1022 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1023 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1024 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1025 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1026 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1027 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1028 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1029 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1030 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1031 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1032 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1033 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1034 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1035 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1036 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1037#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1038 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1039#else
1040 #define JSON_HEDLEY_PRAGMA(value)
1041#endif
1042
1043#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1044 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1045#endif
1046#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1047 #undef JSON_HEDLEY_DIAGNOSTIC_POP
1048#endif
1049#if defined(__clang__)
1050 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1051 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1052#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1053 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1054 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1055#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1056 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1057 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1058#elif \
1059 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1060 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1061 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1062 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1063#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1064 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1065 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1066#elif \
1067 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1068 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1069 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1070 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1071 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1072 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1073 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1074 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1075#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1076 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1077 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1078#else
1079 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
1080 #define JSON_HEDLEY_DIAGNOSTIC_POP
1081#endif
1082
1083/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1084 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1085#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1086 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1087#endif
1088#if defined(__cplusplus)
1089# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1090# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1091# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1092# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1093 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1094 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1095 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1096 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1097 xpr \
1098 JSON_HEDLEY_DIAGNOSTIC_POP
1099# else
1100# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1101 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1102 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1103 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1104 xpr \
1105 JSON_HEDLEY_DIAGNOSTIC_POP
1106# endif
1107# else
1108# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1109 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1110 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1111 xpr \
1112 JSON_HEDLEY_DIAGNOSTIC_POP
1113# endif
1114# endif
1115#endif
1116#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1117 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1118#endif
1119
1120#if defined(JSON_HEDLEY_CONST_CAST)
1121 #undef JSON_HEDLEY_CONST_CAST
1122#endif
1123#if defined(__cplusplus)
1124# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1125#elif \
1126 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1127 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1128 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1129# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1130 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1131 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1132 ((T) (expr)); \
1133 JSON_HEDLEY_DIAGNOSTIC_POP \
1134 }))
1135#else
1136# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1137#endif
1138
1139#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1140 #undef JSON_HEDLEY_REINTERPRET_CAST
1141#endif
1142#if defined(__cplusplus)
1143 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1144#else
1145 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1146#endif
1147
1148#if defined(JSON_HEDLEY_STATIC_CAST)
1149 #undef JSON_HEDLEY_STATIC_CAST
1150#endif
1151#if defined(__cplusplus)
1152 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1153#else
1154 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1155#endif
1156
1157#if defined(JSON_HEDLEY_CPP_CAST)
1158 #undef JSON_HEDLEY_CPP_CAST
1159#endif
1160#if defined(__cplusplus)
1161# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1162# define JSON_HEDLEY_CPP_CAST(T, expr) \
1163 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1164 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1165 ((T) (expr)) \
1166 JSON_HEDLEY_DIAGNOSTIC_POP
1167# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1168# define JSON_HEDLEY_CPP_CAST(T, expr) \
1169 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1170 _Pragma("diag_suppress=Pe137") \
1171 JSON_HEDLEY_DIAGNOSTIC_POP
1172# else
1173# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1174# endif
1175#else
1176# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1177#endif
1178
1179#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1180 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1181#endif
1182#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1183 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1184#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1185 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1186#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1187 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1188#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1189 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1190#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1191 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1192#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1193 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1194#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1195 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1196#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1197 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1198#elif \
1199 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1200 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1201 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1202 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1203 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1204 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1205 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1206 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1207 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1208 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1209 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1210 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1211#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1212 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1213#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1214 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1215#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1216 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1217#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1218 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1219#else
1220 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1221#endif
1222
1223#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1224 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1225#endif
1226#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1227 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1228#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1229 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1230#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1231 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1232#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1233 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1234#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1235 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1236#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1237 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1238#elif \
1239 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1240 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1241 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1242 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1243 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1244#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1245 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1246#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1247 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1248#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1249 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1250#else
1251 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1252#endif
1253
1254#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1255 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1256#endif
1257#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1258 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1259#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1260 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1261#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1262 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1263#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1264 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1265#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1266 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1267#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1268 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1269#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1270 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1271#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1272 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1273#elif \
1274 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1275 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1276 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1277 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1278#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1279 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1280#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1281 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1282#else
1283 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1284#endif
1285
1286#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1287 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1288#endif
1289#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1290 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1291#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1292 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1293#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1294 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1295#else
1296 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1297#endif
1298
1299#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1300 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1301#endif
1302#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1303 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1304#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1305 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1306#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1307 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1308#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1309 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1310#else
1311 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1312#endif
1313
1314#if defined(JSON_HEDLEY_DEPRECATED)
1315 #undef JSON_HEDLEY_DEPRECATED
1316#endif
1317#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1318 #undef JSON_HEDLEY_DEPRECATED_FOR
1319#endif
1320#if \
1321 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1322 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1323 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1324 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1325#elif \
1326 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1327 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1328 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1329 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1330 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1331 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1332 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1333 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1334 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1335 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1336 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1337 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1338 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1339 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1340#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1341 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1342 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1343#elif \
1344 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1345 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1346 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1347 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1348 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1349 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1350 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1351 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1352 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1353 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1354 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1355 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1356 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1357 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1358 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1359 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1360 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1361 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1362#elif \
1363 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1364 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1365 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1366 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1367 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1368#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1369 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1370 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1371#else
1372 #define JSON_HEDLEY_DEPRECATED(since)
1373 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1374#endif
1375
1376#if defined(JSON_HEDLEY_UNAVAILABLE)
1377 #undef JSON_HEDLEY_UNAVAILABLE
1378#endif
1379#if \
1380 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1381 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1382 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1383 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1384 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1385#else
1386 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1387#endif
1388
1389#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1390 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1391#endif
1392#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1393 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1394#endif
1395#if \
1396 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1397 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1398 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1399 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1400 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1401 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1402 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1403 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1404 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1405 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1406 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1407 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1408 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1409 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1410 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1411 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1412 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1413 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1414 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1415#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1416 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1417 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1418#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1419 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1420 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1421#elif defined(_Check_return_) /* SAL */
1422 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1423 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1424#else
1425 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1426 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1427#endif
1428
1429#if defined(JSON_HEDLEY_SENTINEL)
1430 #undef JSON_HEDLEY_SENTINEL
1431#endif
1432#if \
1433 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1434 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1435 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1436 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1437 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1438 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1439#else
1440 #define JSON_HEDLEY_SENTINEL(position)
1441#endif
1442
1443#if defined(JSON_HEDLEY_NO_RETURN)
1444 #undef JSON_HEDLEY_NO_RETURN
1445#endif
1446#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1447 #define JSON_HEDLEY_NO_RETURN __noreturn
1448#elif \
1449 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1450 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1451 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1452#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1453 #define JSON_HEDLEY_NO_RETURN _Noreturn
1454#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1455 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1456#elif \
1457 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1458 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1459 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1460 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1461 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1462 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1463 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1464 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1465 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1466 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1467 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1468 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1469 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1470 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1471 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1472 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1473 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1474 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1475#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1476 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1477#elif \
1478 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1479 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1480 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1481#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1482 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1483#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1484 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1485#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1486 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1487#else
1488 #define JSON_HEDLEY_NO_RETURN
1489#endif
1490
1491#if defined(JSON_HEDLEY_NO_ESCAPE)
1492 #undef JSON_HEDLEY_NO_ESCAPE
1493#endif
1494#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1495 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1496#else
1497 #define JSON_HEDLEY_NO_ESCAPE
1498#endif
1499
1500#if defined(JSON_HEDLEY_UNREACHABLE)
1501 #undef JSON_HEDLEY_UNREACHABLE
1502#endif
1503#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1504 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1505#endif
1506#if defined(JSON_HEDLEY_ASSUME)
1507 #undef JSON_HEDLEY_ASSUME
1508#endif
1509#if \
1510 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1511 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1512 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1513 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1514#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1515 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1516#elif \
1517 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1518 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1519 #if defined(__cplusplus)
1520 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1521 #else
1522 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1523 #endif
1524#endif
1525#if \
1526 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1527 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1528 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1529 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1530 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1531 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1532 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1533 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1534#elif defined(JSON_HEDLEY_ASSUME)
1535 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1536#endif
1537#if !defined(JSON_HEDLEY_ASSUME)
1538 #if defined(JSON_HEDLEY_UNREACHABLE)
1539 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1540 #else
1541 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1542 #endif
1543#endif
1544#if defined(JSON_HEDLEY_UNREACHABLE)
1545 #if \
1546 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1547 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1548 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1549 #else
1550 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1551 #endif
1552#else
1553 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1554#endif
1555#if !defined(JSON_HEDLEY_UNREACHABLE)
1556 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1557#endif
1558
1560#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1561 #pragma clang diagnostic ignored "-Wpedantic"
1562#endif
1563#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1564 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1565#endif
1566#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1567 #if defined(__clang__)
1568 #pragma clang diagnostic ignored "-Wvariadic-macros"
1569 #elif defined(JSON_HEDLEY_GCC_VERSION)
1570 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1571 #endif
1572#endif
1573#if defined(JSON_HEDLEY_NON_NULL)
1574 #undef JSON_HEDLEY_NON_NULL
1575#endif
1576#if \
1577 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1578 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1579 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1580 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1581 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1582#else
1583 #define JSON_HEDLEY_NON_NULL(...)
1584#endif
1586
1587#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1588 #undef JSON_HEDLEY_PRINTF_FORMAT
1589#endif
1590#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1591 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1592#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1593 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1594#elif \
1595 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1596 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1597 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1598 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1599 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1600 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1601 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1602 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1603 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1604 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1605 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1606 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1607 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1608 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1609 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1610 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1611 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1612 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1613#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1614 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1615#else
1616 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1617#endif
1618
1619#if defined(JSON_HEDLEY_CONSTEXPR)
1620 #undef JSON_HEDLEY_CONSTEXPR
1621#endif
1622#if defined(__cplusplus)
1623 #if __cplusplus >= 201103L
1624 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1625 #endif
1626#endif
1627#if !defined(JSON_HEDLEY_CONSTEXPR)
1628 #define JSON_HEDLEY_CONSTEXPR
1629#endif
1630
1631#if defined(JSON_HEDLEY_PREDICT)
1632 #undef JSON_HEDLEY_PREDICT
1633#endif
1634#if defined(JSON_HEDLEY_LIKELY)
1635 #undef JSON_HEDLEY_LIKELY
1636#endif
1637#if defined(JSON_HEDLEY_UNLIKELY)
1638 #undef JSON_HEDLEY_UNLIKELY
1639#endif
1640#if defined(JSON_HEDLEY_UNPREDICTABLE)
1641 #undef JSON_HEDLEY_UNPREDICTABLE
1642#endif
1643#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1644 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1645#endif
1646#if \
1647 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1648 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1649 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1650# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1651# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1652# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1653# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1654# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1655#elif \
1656 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1657 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1658 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1659 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1660 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1661 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1662 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1663 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1664 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1665 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1666 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1667 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1668 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1669 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1670 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1671 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1672# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1673 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1674# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1675 (__extension__ ({ \
1676 double hedley_probability_ = (probability); \
1677 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1678 }))
1679# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1680 (__extension__ ({ \
1681 double hedley_probability_ = (probability); \
1682 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1683 }))
1684# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1685# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1686#else
1687# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1688# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1689# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1690# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1691# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1692#endif
1693#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1694 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1695#endif
1696
1697#if defined(JSON_HEDLEY_MALLOC)
1698 #undef JSON_HEDLEY_MALLOC
1699#endif
1700#if \
1701 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1702 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1703 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1704 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1705 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1706 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1707 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1708 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1709 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1710 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1711 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1712 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1713 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1714 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1715 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1716 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1717 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1718 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1719 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1720#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1721 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1722#elif \
1723 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1724 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1725 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1726#else
1727 #define JSON_HEDLEY_MALLOC
1728#endif
1729
1730#if defined(JSON_HEDLEY_PURE)
1731 #undef JSON_HEDLEY_PURE
1732#endif
1733#if \
1734 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1735 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1736 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1737 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1738 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1739 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1740 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1741 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1743 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1745 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1747 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1748 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1749 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1750 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1751 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1752 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1753# define JSON_HEDLEY_PURE __attribute__((__pure__))
1754#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1755# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1756#elif defined(__cplusplus) && \
1757 ( \
1758 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1759 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1760 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1761 )
1762# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1763#else
1764# define JSON_HEDLEY_PURE
1765#endif
1766
1767#if defined(JSON_HEDLEY_CONST)
1768 #undef JSON_HEDLEY_CONST
1769#endif
1770#if \
1771 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1772 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1773 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1774 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1775 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1776 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1777 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1778 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1779 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1780 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1781 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1782 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1783 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1784 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1785 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1786 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1787 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1788 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1789 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1790 #define JSON_HEDLEY_CONST __attribute__((__const__))
1791#elif \
1792 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1793 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1794#else
1795 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1796#endif
1797
1798#if defined(JSON_HEDLEY_RESTRICT)
1799 #undef JSON_HEDLEY_RESTRICT
1800#endif
1801#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1802 #define JSON_HEDLEY_RESTRICT restrict
1803#elif \
1804 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1805 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1806 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1807 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1808 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1809 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1810 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1811 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1812 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1813 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1814 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1815 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1816 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1817 defined(__clang__) || \
1818 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1819 #define JSON_HEDLEY_RESTRICT __restrict
1820#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1821 #define JSON_HEDLEY_RESTRICT _Restrict
1822#else
1823 #define JSON_HEDLEY_RESTRICT
1824#endif
1825
1826#if defined(JSON_HEDLEY_INLINE)
1827 #undef JSON_HEDLEY_INLINE
1828#endif
1829#if \
1830 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1831 (defined(__cplusplus) && (__cplusplus >= 199711L))
1832 #define JSON_HEDLEY_INLINE inline
1833#elif \
1834 defined(JSON_HEDLEY_GCC_VERSION) || \
1835 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1836 #define JSON_HEDLEY_INLINE __inline__
1837#elif \
1838 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1839 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1840 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1841 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1842 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1843 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1844 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1845 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1846 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1847 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1848 #define JSON_HEDLEY_INLINE __inline
1849#else
1850 #define JSON_HEDLEY_INLINE
1851#endif
1852
1853#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1854 #undef JSON_HEDLEY_ALWAYS_INLINE
1855#endif
1856#if \
1857 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1858 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1859 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1860 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1861 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1862 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1863 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1864 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1865 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1866 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1867 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1868 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1869 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1870 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1871 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1872 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1873 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1874 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1875 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1876# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1877#elif \
1878 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1879 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1880# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1881#elif defined(__cplusplus) && \
1882 ( \
1883 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1884 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1885 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1886 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1887 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1888 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1889 )
1890# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1891#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1892# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1893#else
1894# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1895#endif
1896
1897#if defined(JSON_HEDLEY_NEVER_INLINE)
1898 #undef JSON_HEDLEY_NEVER_INLINE
1899#endif
1900#if \
1901 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1902 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1903 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1904 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1905 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1906 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1907 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1908 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1909 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1910 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1911 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1912 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1913 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1914 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1915 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1916 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1917 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1918 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1919 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1920 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1921#elif \
1922 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1923 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1924 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1925#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1926 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1927#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1928 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1929#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1930 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1931#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1932 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1933#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1934 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1935#else
1936 #define JSON_HEDLEY_NEVER_INLINE
1937#endif
1938
1939#if defined(JSON_HEDLEY_PRIVATE)
1940 #undef JSON_HEDLEY_PRIVATE
1941#endif
1942#if defined(JSON_HEDLEY_PUBLIC)
1943 #undef JSON_HEDLEY_PUBLIC
1944#endif
1945#if defined(JSON_HEDLEY_IMPORT)
1946 #undef JSON_HEDLEY_IMPORT
1947#endif
1948#if defined(_WIN32) || defined(__CYGWIN__)
1949# define JSON_HEDLEY_PRIVATE
1950# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1951# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1952#else
1953# if \
1954 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1955 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1956 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1957 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1958 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1959 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1960 ( \
1961 defined(__TI_EABI__) && \
1962 ( \
1963 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1964 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1965 ) \
1966 ) || \
1967 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1968# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1969# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1970# else
1971# define JSON_HEDLEY_PRIVATE
1972# define JSON_HEDLEY_PUBLIC
1973# endif
1974# define JSON_HEDLEY_IMPORT extern
1975#endif
1976
1977#if defined(JSON_HEDLEY_NO_THROW)
1978 #undef JSON_HEDLEY_NO_THROW
1979#endif
1980#if \
1981 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1982 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1983 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1984 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1985 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1986#elif \
1987 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1988 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1989 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1990 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1991#else
1992 #define JSON_HEDLEY_NO_THROW
1993#endif
1994
1995#if defined(JSON_HEDLEY_FALL_THROUGH)
1996 #undef JSON_HEDLEY_FALL_THROUGH
1997#endif
1998#if \
1999 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2000 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2001 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2002 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2003#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2004 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2005#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2006 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2007#elif defined(__fallthrough) /* SAL */
2008 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
2009#else
2010 #define JSON_HEDLEY_FALL_THROUGH
2011#endif
2012
2013#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2014 #undef JSON_HEDLEY_RETURNS_NON_NULL
2015#endif
2016#if \
2017 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2018 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2019 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2020 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2021#elif defined(_Ret_notnull_) /* SAL */
2022 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2023#else
2024 #define JSON_HEDLEY_RETURNS_NON_NULL
2025#endif
2026
2027#if defined(JSON_HEDLEY_ARRAY_PARAM)
2028 #undef JSON_HEDLEY_ARRAY_PARAM
2029#endif
2030#if \
2031 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2032 !defined(__STDC_NO_VLA__) && \
2033 !defined(__cplusplus) && \
2034 !defined(JSON_HEDLEY_PGI_VERSION) && \
2035 !defined(JSON_HEDLEY_TINYC_VERSION)
2036 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2037#else
2038 #define JSON_HEDLEY_ARRAY_PARAM(name)
2039#endif
2040
2041#if defined(JSON_HEDLEY_IS_CONSTANT)
2042 #undef JSON_HEDLEY_IS_CONSTANT
2043#endif
2044#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2045 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2046#endif
2047/* JSON_HEDLEY_IS_CONSTEXPR_ is for
2048 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2049#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2050 #undef JSON_HEDLEY_IS_CONSTEXPR_
2051#endif
2052#if \
2053 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2054 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2055 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2056 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2057 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2058 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2059 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2060 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2061 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2062 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2063 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2064#endif
2065#if !defined(__cplusplus)
2066# if \
2067 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2068 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2069 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2070 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2071 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2072 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2073 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2074#if defined(__INTPTR_TYPE__)
2075 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2076#else
2077 #include <stdint.h>
2078 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2079#endif
2080# elif \
2081 ( \
2082 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2083 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2084 !defined(JSON_HEDLEY_PGI_VERSION) && \
2085 !defined(JSON_HEDLEY_IAR_VERSION)) || \
2086 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2087 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2088 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2089 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2090 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2091#if defined(__INTPTR_TYPE__)
2092 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2093#else
2094 #include <stdint.h>
2095 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2096#endif
2097# elif \
2098 defined(JSON_HEDLEY_GCC_VERSION) || \
2099 defined(JSON_HEDLEY_INTEL_VERSION) || \
2100 defined(JSON_HEDLEY_TINYC_VERSION) || \
2101 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2102 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2103 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2104 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2105 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2106 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2107 defined(__clang__)
2108# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2109 sizeof(void) != \
2110 sizeof(*( \
2111 1 ? \
2112 ((void*) ((expr) * 0L) ) : \
2113((struct { char v[sizeof(void) * 2]; } *) 1) \
2114 ) \
2115 ) \
2116 )
2117# endif
2118#endif
2119#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2120 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2121 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2122 #endif
2123 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2124#else
2125 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2126 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2127 #endif
2128 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2129#endif
2130
2131#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2132 #undef JSON_HEDLEY_BEGIN_C_DECLS
2133#endif
2134#if defined(JSON_HEDLEY_END_C_DECLS)
2135 #undef JSON_HEDLEY_END_C_DECLS
2136#endif
2137#if defined(JSON_HEDLEY_C_DECL)
2138 #undef JSON_HEDLEY_C_DECL
2139#endif
2140#if defined(__cplusplus)
2141 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2142 #define JSON_HEDLEY_END_C_DECLS }
2143 #define JSON_HEDLEY_C_DECL extern "C"
2144#else
2145 #define JSON_HEDLEY_BEGIN_C_DECLS
2146 #define JSON_HEDLEY_END_C_DECLS
2147 #define JSON_HEDLEY_C_DECL
2148#endif
2149
2150#if defined(JSON_HEDLEY_STATIC_ASSERT)
2151 #undef JSON_HEDLEY_STATIC_ASSERT
2152#endif
2153#if \
2154 !defined(__cplusplus) && ( \
2155 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2156 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2157 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2158 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2159 defined(_Static_assert) \
2160 )
2161# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2162#elif \
2163 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2164 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2165 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2166# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2167#else
2168# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2169#endif
2170
2171#if defined(JSON_HEDLEY_NULL)
2172 #undef JSON_HEDLEY_NULL
2173#endif
2174#if defined(__cplusplus)
2175 #if __cplusplus >= 201103L
2176 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2177 #elif defined(NULL)
2178 #define JSON_HEDLEY_NULL NULL
2179 #else
2180 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2181 #endif
2182#elif defined(NULL)
2183 #define JSON_HEDLEY_NULL NULL
2184#else
2185 #define JSON_HEDLEY_NULL ((void*) 0)
2186#endif
2187
2188#if defined(JSON_HEDLEY_MESSAGE)
2189 #undef JSON_HEDLEY_MESSAGE
2190#endif
2191#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2192# define JSON_HEDLEY_MESSAGE(msg) \
2193 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2194 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2195 JSON_HEDLEY_PRAGMA(message msg) \
2196 JSON_HEDLEY_DIAGNOSTIC_POP
2197#elif \
2198 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2199 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2200# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2201#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2202# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2203#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2204# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2205#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2206# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2207#else
2208# define JSON_HEDLEY_MESSAGE(msg)
2209#endif
2210
2211#if defined(JSON_HEDLEY_WARNING)
2212 #undef JSON_HEDLEY_WARNING
2213#endif
2214#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2215# define JSON_HEDLEY_WARNING(msg) \
2216 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2217 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2218 JSON_HEDLEY_PRAGMA(clang warning msg) \
2219 JSON_HEDLEY_DIAGNOSTIC_POP
2220#elif \
2221 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2222 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2223 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2224# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2225#elif \
2226 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2227 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2228# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2229#else
2230# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2231#endif
2232
2233#if defined(JSON_HEDLEY_REQUIRE)
2234 #undef JSON_HEDLEY_REQUIRE
2235#endif
2236#if defined(JSON_HEDLEY_REQUIRE_MSG)
2237 #undef JSON_HEDLEY_REQUIRE_MSG
2238#endif
2239#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2240# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2241# define JSON_HEDLEY_REQUIRE(expr) \
2242 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2243 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2244 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2245 JSON_HEDLEY_DIAGNOSTIC_POP
2246# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2247 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2248 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2249 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2250 JSON_HEDLEY_DIAGNOSTIC_POP
2251# else
2252# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2253# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2254# endif
2255#else
2256# define JSON_HEDLEY_REQUIRE(expr)
2257# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2258#endif
2259
2260#if defined(JSON_HEDLEY_FLAGS)
2261 #undef JSON_HEDLEY_FLAGS
2262#endif
2263#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2264 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2265#else
2266 #define JSON_HEDLEY_FLAGS
2267#endif
2268
2269#if defined(JSON_HEDLEY_FLAGS_CAST)
2270 #undef JSON_HEDLEY_FLAGS_CAST
2271#endif
2272#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2273# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2274 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2275 _Pragma("warning(disable:188)") \
2276 ((T) (expr)); \
2277 JSON_HEDLEY_DIAGNOSTIC_POP \
2278 }))
2279#else
2280# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2281#endif
2282
2283#if defined(JSON_HEDLEY_EMPTY_BASES)
2284 #undef JSON_HEDLEY_EMPTY_BASES
2285#endif
2286#if \
2287 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2288 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2289 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2290#else
2291 #define JSON_HEDLEY_EMPTY_BASES
2292#endif
2293
2294/* Remaining macros are deprecated. */
2295
2296#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2297 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2298#endif
2299#if defined(__clang__)
2300 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2301#else
2302 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2303#endif
2304
2305#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2306 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2307#endif
2308#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2309
2310#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2311 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2312#endif
2313#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2314
2315#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2316 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2317#endif
2318#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2319
2320#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2321 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2322#endif
2323#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2324
2325#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2326 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2327#endif
2328#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2329
2330#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2331 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2332#endif
2333#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2334
2335#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2336 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2337#endif
2338#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2339
2340#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2341
2342
2343// This file contains all internal macro definitions (except those affecting ABI)
2344// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2345
2346// #include <nlohmann/detail/abi_macros.hpp>
2347
2348
2349// exclude unsupported compilers
2350#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2351 #if defined(__clang__)
2352 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2353 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2354 #endif
2355 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2356 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2357 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2358 #endif
2359 #endif
2360#endif
2361
2362// C++ language standard detection
2363// if the user manually specified the used c++ version this is skipped
2364#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2365 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2366 #define JSON_HAS_CPP_20
2367 #define JSON_HAS_CPP_17
2368 #define JSON_HAS_CPP_14
2369 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2370 #define JSON_HAS_CPP_17
2371 #define JSON_HAS_CPP_14
2372 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2373 #define JSON_HAS_CPP_14
2374 #endif
2375 // the cpp 11 flag is always specified because it is the minimal required version
2376 #define JSON_HAS_CPP_11
2377#endif
2378
2379#ifdef __has_include
2380 #if __has_include(<version>)
2381 #include <version>
2382 #endif
2383#endif
2384
2385#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2386 #ifdef JSON_HAS_CPP_17
2387 #if defined(__cpp_lib_filesystem)
2388 #define JSON_HAS_FILESYSTEM 1
2389 #elif defined(__cpp_lib_experimental_filesystem)
2390 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2391 #elif !defined(__has_include)
2392 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2393 #elif __has_include(<filesystem>)
2394 #define JSON_HAS_FILESYSTEM 1
2395 #elif __has_include(<experimental/filesystem>)
2396 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2397 #endif
2398
2399 // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2400 #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2401 #undef JSON_HAS_FILESYSTEM
2402 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2403 #endif
2404
2405 // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2406 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2407 #undef JSON_HAS_FILESYSTEM
2408 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2409 #endif
2410
2411 // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2412 #if defined(__clang_major__) && __clang_major__ < 7
2413 #undef JSON_HAS_FILESYSTEM
2414 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2415 #endif
2416
2417 // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2418 #if defined(_MSC_VER) && _MSC_VER < 1914
2419 #undef JSON_HAS_FILESYSTEM
2420 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2421 #endif
2422
2423 // no filesystem support before iOS 13
2424 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2425 #undef JSON_HAS_FILESYSTEM
2426 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2427 #endif
2428
2429 // no filesystem support before macOS Catalina
2430 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2431 #undef JSON_HAS_FILESYSTEM
2432 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2433 #endif
2434 #endif
2435#endif
2436
2437#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2438 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2439#endif
2440
2441#ifndef JSON_HAS_FILESYSTEM
2442 #define JSON_HAS_FILESYSTEM 0
2443#endif
2444
2445#ifndef JSON_HAS_THREE_WAY_COMPARISON
2446 #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2447 && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2448 #define JSON_HAS_THREE_WAY_COMPARISON 1
2449 #else
2450 #define JSON_HAS_THREE_WAY_COMPARISON 0
2451 #endif
2452#endif
2453
2454#ifndef JSON_HAS_RANGES
2455 // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2456 #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2457 #define JSON_HAS_RANGES 0
2458 #elif defined(__cpp_lib_ranges)
2459 #define JSON_HAS_RANGES 1
2460 #else
2461 #define JSON_HAS_RANGES 0
2462 #endif
2463#endif
2464
2465#ifdef JSON_HAS_CPP_17
2466 #define JSON_INLINE_VARIABLE inline
2467#else
2468 #define JSON_INLINE_VARIABLE
2469#endif
2470
2471#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2472 #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2473#else
2474 #define JSON_NO_UNIQUE_ADDRESS
2475#endif
2476
2477// disable documentation warnings on clang
2478#if defined(__clang__)
2479 #pragma clang diagnostic push
2480 #pragma clang diagnostic ignored "-Wdocumentation"
2481 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2482#endif
2483
2484// allow disabling exceptions
2485#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2486 #define JSON_THROW(exception) throw exception
2487 #define JSON_TRY try
2488 #define JSON_CATCH(exception) catch(exception)
2489 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2490#else
2491 #include <cstdlib>
2492 #define JSON_THROW(exception) std::abort()
2493 #define JSON_TRY if(true)
2494 #define JSON_CATCH(exception) if(false)
2495 #define JSON_INTERNAL_CATCH(exception) if(false)
2496#endif
2497
2498// override exception macros
2499#if defined(JSON_THROW_USER)
2500 #undef JSON_THROW
2501 #define JSON_THROW JSON_THROW_USER
2502#endif
2503#if defined(JSON_TRY_USER)
2504 #undef JSON_TRY
2505 #define JSON_TRY JSON_TRY_USER
2506#endif
2507#if defined(JSON_CATCH_USER)
2508 #undef JSON_CATCH
2509 #define JSON_CATCH JSON_CATCH_USER
2510 #undef JSON_INTERNAL_CATCH
2511 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2512#endif
2513#if defined(JSON_INTERNAL_CATCH_USER)
2514 #undef JSON_INTERNAL_CATCH
2515 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2516#endif
2517
2518// allow overriding assert
2519#if !defined(JSON_ASSERT)
2520 #include <cassert> // assert
2521 #define JSON_ASSERT(x) assert(x)
2522#endif
2523
2524// allow to access some private functions (needed by the test suite)
2525#if defined(JSON_TESTS_PRIVATE)
2526 #define JSON_PRIVATE_UNLESS_TESTED public
2527#else
2528 #define JSON_PRIVATE_UNLESS_TESTED private
2529#endif
2530
2536#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2537 template<typename BasicJsonType> \
2538 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2539 { \
2540 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2541 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2542 auto it = std::find_if(std::begin(m), std::end(m), \
2543 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2544 { \
2545 return ej_pair.first == e; \
2546 }); \
2547 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2548 } \
2549 template<typename BasicJsonType> \
2550 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2551 { \
2552 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2553 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2554 auto it = std::find_if(std::begin(m), std::end(m), \
2555 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2556 { \
2557 return ej_pair.second == j; \
2558 }); \
2559 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2560 }
2561
2562// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2563// may be removed in the future once the class is split.
2564
2565#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2566 template<template<typename, typename, typename...> class ObjectType, \
2567 template<typename, typename...> class ArrayType, \
2568 class StringType, class BooleanType, class NumberIntegerType, \
2569 class NumberUnsignedType, class NumberFloatType, \
2570 template<typename> class AllocatorType, \
2571 template<typename, typename = void> class JSONSerializer, \
2572 class BinaryType>
2573
2574#define NLOHMANN_BASIC_JSON_TPL \
2575 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2576 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2577 AllocatorType, JSONSerializer, BinaryType>
2578
2579// Macros to simplify conversion from/to types
2580
2581#define NLOHMANN_JSON_EXPAND( x ) x
2582#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2583#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2584 NLOHMANN_JSON_PASTE64, \
2585 NLOHMANN_JSON_PASTE63, \
2586 NLOHMANN_JSON_PASTE62, \
2587 NLOHMANN_JSON_PASTE61, \
2588 NLOHMANN_JSON_PASTE60, \
2589 NLOHMANN_JSON_PASTE59, \
2590 NLOHMANN_JSON_PASTE58, \
2591 NLOHMANN_JSON_PASTE57, \
2592 NLOHMANN_JSON_PASTE56, \
2593 NLOHMANN_JSON_PASTE55, \
2594 NLOHMANN_JSON_PASTE54, \
2595 NLOHMANN_JSON_PASTE53, \
2596 NLOHMANN_JSON_PASTE52, \
2597 NLOHMANN_JSON_PASTE51, \
2598 NLOHMANN_JSON_PASTE50, \
2599 NLOHMANN_JSON_PASTE49, \
2600 NLOHMANN_JSON_PASTE48, \
2601 NLOHMANN_JSON_PASTE47, \
2602 NLOHMANN_JSON_PASTE46, \
2603 NLOHMANN_JSON_PASTE45, \
2604 NLOHMANN_JSON_PASTE44, \
2605 NLOHMANN_JSON_PASTE43, \
2606 NLOHMANN_JSON_PASTE42, \
2607 NLOHMANN_JSON_PASTE41, \
2608 NLOHMANN_JSON_PASTE40, \
2609 NLOHMANN_JSON_PASTE39, \
2610 NLOHMANN_JSON_PASTE38, \
2611 NLOHMANN_JSON_PASTE37, \
2612 NLOHMANN_JSON_PASTE36, \
2613 NLOHMANN_JSON_PASTE35, \
2614 NLOHMANN_JSON_PASTE34, \
2615 NLOHMANN_JSON_PASTE33, \
2616 NLOHMANN_JSON_PASTE32, \
2617 NLOHMANN_JSON_PASTE31, \
2618 NLOHMANN_JSON_PASTE30, \
2619 NLOHMANN_JSON_PASTE29, \
2620 NLOHMANN_JSON_PASTE28, \
2621 NLOHMANN_JSON_PASTE27, \
2622 NLOHMANN_JSON_PASTE26, \
2623 NLOHMANN_JSON_PASTE25, \
2624 NLOHMANN_JSON_PASTE24, \
2625 NLOHMANN_JSON_PASTE23, \
2626 NLOHMANN_JSON_PASTE22, \
2627 NLOHMANN_JSON_PASTE21, \
2628 NLOHMANN_JSON_PASTE20, \
2629 NLOHMANN_JSON_PASTE19, \
2630 NLOHMANN_JSON_PASTE18, \
2631 NLOHMANN_JSON_PASTE17, \
2632 NLOHMANN_JSON_PASTE16, \
2633 NLOHMANN_JSON_PASTE15, \
2634 NLOHMANN_JSON_PASTE14, \
2635 NLOHMANN_JSON_PASTE13, \
2636 NLOHMANN_JSON_PASTE12, \
2637 NLOHMANN_JSON_PASTE11, \
2638 NLOHMANN_JSON_PASTE10, \
2639 NLOHMANN_JSON_PASTE9, \
2640 NLOHMANN_JSON_PASTE8, \
2641 NLOHMANN_JSON_PASTE7, \
2642 NLOHMANN_JSON_PASTE6, \
2643 NLOHMANN_JSON_PASTE5, \
2644 NLOHMANN_JSON_PASTE4, \
2645 NLOHMANN_JSON_PASTE3, \
2646 NLOHMANN_JSON_PASTE2, \
2647 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2648#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2649#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2650#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2651#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2652#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2653#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2654#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2655#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2656#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2657#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2658#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2659#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2660#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2661#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2662#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2663#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2664#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2665#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2666#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2667#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2668#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2669#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2670#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2671#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2672#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2673#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2674#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2675#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2676#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2677#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2678#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2679#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2680#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2681#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2682#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2683#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2684#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2685#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2686#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2687#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2688#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2689#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2690#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2691#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2692#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2693#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2694#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2695#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2696#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2697#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2698#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2699#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2700#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2701#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2702#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2703#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2704#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2705#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2706#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2707#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2708#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2709#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2710#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2711
2712#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2713#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2714#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2715
2721#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2722 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2723 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2724
2725#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2726 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2727 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2728
2734#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2735 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2736 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2737
2738#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2739 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2740 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2741
2742
2743// inspired from https://stackoverflow.com/a/26745591
2744// allows to call any std function as if (e.g. with begin):
2745// using std::begin; begin(x);
2746//
2747// it allows using the detected idiom to retrieve the return type
2748// of such an expression
2749#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2750 namespace detail { \
2751 using std::std_name; \
2752 \
2753 template<typename... T> \
2754 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2755 } \
2756 \
2757 namespace detail2 { \
2758 struct std_name##_tag \
2759 { \
2760 }; \
2761 \
2762 template<typename... T> \
2763 std_name##_tag std_name(T&&...); \
2764 \
2765 template<typename... T> \
2766 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2767 \
2768 template<typename... T> \
2769 struct would_call_std_##std_name \
2770 { \
2771 static constexpr auto const value = ::nlohmann::detail:: \
2772 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2773 }; \
2774 } /* namespace detail2 */ \
2775 \
2776 template<typename... T> \
2777 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2778 { \
2779 }
2780
2781#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2782 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2783#endif
2784
2785#if JSON_USE_IMPLICIT_CONVERSIONS
2786 #define JSON_EXPLICIT
2787#else
2788 #define JSON_EXPLICIT explicit
2789#endif
2790
2791#ifndef JSON_DISABLE_ENUM_SERIALIZATION
2792 #define JSON_DISABLE_ENUM_SERIALIZATION 0
2793#endif
2794
2795#ifndef JSON_USE_GLOBAL_UDLS
2796 #define JSON_USE_GLOBAL_UDLS 1
2797#endif
2798
2799#if JSON_HAS_THREE_WAY_COMPARISON
2800 #include <compare> // partial_ordering
2801#endif
2802
2804namespace detail
2805{
2806
2808// JSON type enumeration //
2810
2835enum class value_t : std::uint8_t
2836{
2837 null,
2838 object,
2839 array,
2840 string,
2841 boolean,
2844 number_float,
2845 binary,
2846 discarded
2847};
2848
2862#if JSON_HAS_THREE_WAY_COMPARISON
2863 inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2864#else
2865 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2866#endif
2867{
2868 static constexpr std::array<std::uint8_t, 9> order = {{
2869 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2870 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2871 6 /* binary */
2872 }
2873 };
2874
2875 const auto l_index = static_cast<std::size_t>(lhs);
2876 const auto r_index = static_cast<std::size_t>(rhs);
2877#if JSON_HAS_THREE_WAY_COMPARISON
2878 if (l_index < order.size() && r_index < order.size())
2879 {
2880 return order[l_index] <=> order[r_index]; // *NOPAD*
2881 }
2882 return std::partial_ordering::unordered;
2883#else
2884 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2885#endif
2886}
2887
2888// GCC selects the built-in operator< over an operator rewritten from
2889// a user-defined spaceship operator
2890// Clang, MSVC, and ICC select the rewritten candidate
2891// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2892#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2893inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2894{
2895 return std::is_lt(lhs <=> rhs); // *NOPAD*
2896}
2897#endif
2898
2899} // namespace detail
2901
2902// #include <nlohmann/detail/string_escape.hpp>
2903// __ _____ _____ _____
2904// __| | __| | | | JSON for Modern C++
2905// | | |__ | | | | | | version 3.11.1
2906// |_____|_____|_____|_|___| https://github.com/nlohmann/json
2907//
2908// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
2909// SPDX-License-Identifier: MIT
2910
2911
2912
2913// #include <nlohmann/detail/abi_macros.hpp>
2914
2915
2917namespace detail
2918{
2919
2933template<typename StringType>
2934inline void replace_substring(StringType& s, const StringType& f,
2935 const StringType& t)
2936{
2937 JSON_ASSERT(!f.empty());
2938 for (auto pos = s.find(f); // find first occurrence of f
2939 pos != StringType::npos; // make sure f was found
2940 s.replace(pos, f.size(), t), // replace with t, and
2941 pos = s.find(f, pos + t.size())) // find next occurrence of f
2942 {}
2943}
2944
2952template<typename StringType>
2953inline StringType escape(StringType s)
2954{
2955 replace_substring(s, StringType{"~"}, StringType{"~0"});
2956 replace_substring(s, StringType{"/"}, StringType{"~1"});
2957 return s;
2958}
2959
2967template<typename StringType>
2968static void unescape(StringType& s)
2969{
2970 replace_substring(s, StringType{"~1"}, StringType{"/"});
2971 replace_substring(s, StringType{"~0"}, StringType{"~"});
2972}
2973
2974} // namespace detail
2976
2977// #include <nlohmann/detail/input/position_t.hpp>
2978// __ _____ _____ _____
2979// __| | __| | | | JSON for Modern C++
2980// | | |__ | | | | | | version 3.11.1
2981// |_____|_____|_____|_|___| https://github.com/nlohmann/json
2982//
2983// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
2984// SPDX-License-Identifier: MIT
2985
2986
2987
2988#include <cstddef> // size_t
2989
2990// #include <nlohmann/detail/abi_macros.hpp>
2991
2992
2994namespace detail
2995{
2996
2999{
3001 std::size_t chars_read_total = 0;
3005 std::size_t lines_read = 0;
3006
3008 constexpr operator size_t() const
3009 {
3010 return chars_read_total;
3011 }
3012};
3013
3014} // namespace detail
3016
3017// #include <nlohmann/detail/macro_scope.hpp>
3018
3019// #include <nlohmann/detail/meta/cpp_future.hpp>
3020// __ _____ _____ _____
3021// __| | __| | | | JSON for Modern C++
3022// | | |__ | | | | | | version 3.11.1
3023// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3024//
3025// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3026// SPDX-FileCopyrightText: 2018 The Abseil Authors
3027// SPDX-License-Identifier: MIT
3028
3029
3030
3031#include <cstddef> // size_t
3032#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3033#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3034
3035// #include <nlohmann/detail/macro_scope.hpp>
3036
3037
3039namespace detail
3040{
3041
3042template<typename T>
3043using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3044
3045#ifdef JSON_HAS_CPP_14
3046
3047// the following utilities are natively available in C++14
3048using std::enable_if_t;
3052
3053#else
3054
3055// alias templates to reduce boilerplate
3056template<bool B, typename T = void>
3057using enable_if_t = typename std::enable_if<B, T>::type;
3058
3059// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3060// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3061
3063
3064// integer_sequence
3065//
3066// Class template representing a compile-time integer sequence. An instantiation
3067// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3068// type through its template arguments (which is a common need when
3069// working with C++11 variadic templates). `absl::integer_sequence` is designed
3070// to be a drop-in replacement for C++14's `std::integer_sequence`.
3071//
3072// Example:
3073//
3074// template< class T, T... Ints >
3075// void user_function(integer_sequence<T, Ints...>);
3076//
3077// int main()
3078// {
3079// // user_function's `T` will be deduced to `int` and `Ints...`
3080// // will be deduced to `0, 1, 2, 3, 4`.
3081// user_function(make_integer_sequence<int, 5>());
3082// }
3083template <typename T, T... Ints>
3085{
3086 using value_type = T;
3087 static constexpr std::size_t size() noexcept
3088 {
3089 return sizeof...(Ints);
3090 }
3091};
3092
3093// index_sequence
3094//
3095// A helper template for an `integer_sequence` of `size_t`,
3096// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3097// `std::index_sequence`.
3098template <size_t... Ints>
3099using index_sequence = integer_sequence<size_t, Ints...>;
3100
3101namespace utility_internal
3102{
3103
3104template <typename Seq, size_t SeqSize, size_t Rem>
3105struct Extend;
3106
3107// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3108template <typename T, T... Ints, size_t SeqSize>
3109struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3110{
3111 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3112};
3113
3114template <typename T, T... Ints, size_t SeqSize>
3115struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3116{
3117 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3118};
3119
3120// Recursion helper for 'make_integer_sequence<T, N>'.
3121// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3122template <typename T, size_t N>
3123struct Gen
3124{
3125 using type =
3126 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3127};
3128
3129template <typename T>
3130struct Gen<T, 0>
3131{
3133};
3134
3135} // namespace utility_internal
3136
3137// Compile-time sequences of integers
3138
3139// make_integer_sequence
3140//
3141// This template alias is equivalent to
3142// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3143// replacement for C++14's `std::make_integer_sequence`.
3144template <typename T, T N>
3146
3147// make_index_sequence
3148//
3149// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3150// and is designed to be a drop-in replacement for C++14's
3151// `std::make_index_sequence`.
3152template <size_t N>
3154
3155// index_sequence_for
3156//
3157// Converts a typename pack into an index sequence of the same length, and
3158// is designed to be a drop-in replacement for C++14's
3159// `std::index_sequence_for()`
3160template <typename... Ts>
3162
3164
3165#endif
3166
3167// dispatch utility (taken from ranges-v3)
3168template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3169template<> struct priority_tag<0> {};
3170
3171// taken from ranges-v3
3172template<typename T>
3174{
3175 static constexpr T value{};
3176};
3177
3178#ifndef JSON_HAS_CPP_17
3179
3180 template<typename T>
3181 constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
3182
3183#endif
3184
3185} // namespace detail
3187
3188// #include <nlohmann/detail/meta/type_traits.hpp>
3189// __ _____ _____ _____
3190// __| | __| | | | JSON for Modern C++
3191// | | |__ | | | | | | version 3.11.1
3192// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3193//
3194// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3195// SPDX-License-Identifier: MIT
3196
3197
3198
3199#include <limits> // numeric_limits
3200#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3201#include <utility> // declval
3202#include <tuple> // tuple
3203
3204// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3205// __ _____ _____ _____
3206// __| | __| | | | JSON for Modern C++
3207// | | |__ | | | | | | version 3.11.1
3208// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3209//
3210// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3211// SPDX-License-Identifier: MIT
3212
3213
3214
3215#include <iterator> // random_access_iterator_tag
3216
3217// #include <nlohmann/detail/abi_macros.hpp>
3218
3219// #include <nlohmann/detail/meta/void_t.hpp>
3220
3221// #include <nlohmann/detail/meta/cpp_future.hpp>
3222
3223
3225namespace detail
3226{
3227
3228template<typename It, typename = void>
3230
3231template<typename It>
3233 It,
3234 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3235 typename It::reference, typename It::iterator_category >>
3236{
3237 using difference_type = typename It::difference_type;
3238 using value_type = typename It::value_type;
3239 using pointer = typename It::pointer;
3240 using reference = typename It::reference;
3241 using iterator_category = typename It::iterator_category;
3242};
3243
3244// This is required as some compilers implement std::iterator_traits in a way that
3245// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3246template<typename T, typename = void>
3248{
3249};
3250
3251template<typename T>
3252struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3253 : iterator_types<T>
3254{
3255};
3256
3257template<typename T>
3259{
3260 using iterator_category = std::random_access_iterator_tag;
3261 using value_type = T;
3262 using difference_type = ptrdiff_t;
3263 using pointer = T*;
3264 using reference = T&;
3265};
3266
3267} // namespace detail
3269
3270// #include <nlohmann/detail/macro_scope.hpp>
3271
3272// #include <nlohmann/detail/meta/call_std/begin.hpp>
3273// __ _____ _____ _____
3274// __| | __| | | | JSON for Modern C++
3275// | | |__ | | | | | | version 3.11.1
3276// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3277//
3278// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3279// SPDX-License-Identifier: MIT
3280
3281
3282
3283// #include <nlohmann/detail/macro_scope.hpp>
3284
3285
3287
3289
3291
3292// #include <nlohmann/detail/meta/call_std/end.hpp>
3293// __ _____ _____ _____
3294// __| | __| | | | JSON for Modern C++
3295// | | |__ | | | | | | version 3.11.1
3296// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3297//
3298// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3299// SPDX-License-Identifier: MIT
3300
3301
3302
3303// #include <nlohmann/detail/macro_scope.hpp>
3304
3305
3307
3309
3311
3312// #include <nlohmann/detail/meta/cpp_future.hpp>
3313
3314// #include <nlohmann/detail/meta/detected.hpp>
3315
3316// #include <nlohmann/json_fwd.hpp>
3317// __ _____ _____ _____
3318// __| | __| | | | JSON for Modern C++
3319// | | |__ | | | | | | version 3.11.1
3320// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3321//
3322// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3323// SPDX-License-Identifier: MIT
3324
3325#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3326 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3327
3328 #include <cstdint> // int64_t, uint64_t
3329 #include <map> // map
3330 #include <memory> // allocator
3331 #include <string> // string
3332 #include <vector> // vector
3333
3334 // #include <nlohmann/detail/abi_macros.hpp>
3335
3336
3343
3351 template<typename T = void, typename SFINAE = void>
3352 struct adl_serializer;
3353
3356 template<template<typename U, typename V, typename... Args> class ObjectType =
3357 std::map,
3358 template<typename U, typename... Args> class ArrayType = std::vector,
3359 class StringType = std::string, class BooleanType = bool,
3360 class NumberIntegerType = std::int64_t,
3361 class NumberUnsignedType = std::uint64_t,
3362 class NumberFloatType = double,
3363 template<typename U> class AllocatorType = std::allocator,
3364 template<typename T, typename SFINAE = void> class JSONSerializer =
3366 class BinaryType = std::vector<std::uint8_t>>
3367 class basic_json;
3368
3371 template<typename BasicJsonType>
3372 class json_pointer;
3373
3379
3382 template<class Key, class T, class IgnoredLess, class Allocator>
3383 struct ordered_map;
3384
3388
3390
3391#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3392
3393
3403namespace detail
3404{
3405
3407// helpers //
3409
3410// Note to maintainers:
3411//
3412// Every trait in this file expects a non CV-qualified type.
3413// The only exceptions are in the 'aliases for detected' section
3414// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3415//
3416// In this case, T has to be properly CV-qualified to constraint the function arguments
3417// (e.g. to_json(BasicJsonType&, const T&))
3418
3419template<typename> struct is_basic_json : std::false_type {};
3420
3422struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3423
3424// used by exceptions create() member functions
3425// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3426// false_type otherwise
3427template<typename BasicJsonContext>
3429 std::integral_constant < bool,
3430 is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3431 || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3432{};
3433
3435// json_ref helpers //
3437
3438template<typename>
3439class json_ref;
3440
3441template<typename>
3442struct is_json_ref : std::false_type {};
3443
3444template<typename T>
3445struct is_json_ref<json_ref<T>> : std::true_type {};
3446
3448// aliases for detected //
3450
3451template<typename T>
3452using mapped_type_t = typename T::mapped_type;
3453
3454template<typename T>
3455using key_type_t = typename T::key_type;
3456
3457template<typename T>
3458using value_type_t = typename T::value_type;
3459
3460template<typename T>
3461using difference_type_t = typename T::difference_type;
3462
3463template<typename T>
3464using pointer_t = typename T::pointer;
3465
3466template<typename T>
3467using reference_t = typename T::reference;
3468
3469template<typename T>
3470using iterator_category_t = typename T::iterator_category;
3471
3472template<typename T, typename... Args>
3473using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3474
3475template<typename T, typename... Args>
3476using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3477
3478template<typename T, typename U>
3479using get_template_function = decltype(std::declval<T>().template get<U>());
3480
3481// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3482template<typename BasicJsonType, typename T, typename = void>
3483struct has_from_json : std::false_type {};
3484
3485// trait checking if j.get<T> is valid
3486// use this trait instead of std::is_constructible or std::is_convertible,
3487// both rely on, or make use of implicit conversions, and thus fail when T
3488// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3489template <typename BasicJsonType, typename T>
3491{
3493};
3494
3495template<typename BasicJsonType, typename T>
3496struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3497{
3498 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3499
3500 static constexpr bool value =
3502 const BasicJsonType&, T&>::value;
3503};
3504
3505// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3506// this overload is used for non-default-constructible user-defined-types
3507template<typename BasicJsonType, typename T, typename = void>
3508struct has_non_default_from_json : std::false_type {};
3509
3510template<typename BasicJsonType, typename T>
3511struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3512{
3513 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3514
3515 static constexpr bool value =
3517 const BasicJsonType&>::value;
3518};
3519
3520// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3521// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3522template<typename BasicJsonType, typename T, typename = void>
3523struct has_to_json : std::false_type {};
3524
3525template<typename BasicJsonType, typename T>
3526struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3527{
3528 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3529
3530 static constexpr bool value =
3531 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3532 T>::value;
3533};
3534
3535template<typename T>
3536using detect_key_compare = typename T::key_compare;
3537
3538template<typename T>
3539struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3540
3541// obtains the actual object key comparator
3542template<typename BasicJsonType>
3544{
3545 using object_t = typename BasicJsonType::object_t;
3546 using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3547 using type = typename std::conditional < has_key_compare<object_t>::value,
3548 typename object_t::key_compare, object_comparator_t>::type;
3549};
3550
3551template<typename BasicJsonType>
3553
3555// is_ functions //
3557
3558// https://en.cppreference.com/w/cpp/types/conjunction
3559template<class...> struct conjunction : std::true_type { };
3560template<class B> struct conjunction<B> : B { };
3561template<class B, class... Bn>
3562struct conjunction<B, Bn...>
3563: std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3564
3565// https://en.cppreference.com/w/cpp/types/negation
3566template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3567
3568// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3569// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3570// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3571template <typename T>
3572struct is_default_constructible : std::is_default_constructible<T> {};
3573
3574template <typename T1, typename T2>
3575struct is_default_constructible<std::pair<T1, T2>>
3576 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3577
3578template <typename T1, typename T2>
3579struct is_default_constructible<const std::pair<T1, T2>>
3580 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3581
3582template <typename... Ts>
3583struct is_default_constructible<std::tuple<Ts...>>
3584 : conjunction<is_default_constructible<Ts>...> {};
3585
3586template <typename... Ts>
3587struct is_default_constructible<const std::tuple<Ts...>>
3588 : conjunction<is_default_constructible<Ts>...> {};
3589
3590
3591template <typename T, typename... Args>
3592struct is_constructible : std::is_constructible<T, Args...> {};
3593
3594template <typename T1, typename T2>
3595struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3596
3597template <typename T1, typename T2>
3598struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3599
3600template <typename... Ts>
3601struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3602
3603template <typename... Ts>
3604struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3605
3606
3607template<typename T, typename = void>
3608struct is_iterator_traits : std::false_type {};
3609
3610template<typename T>
3612{
3613 private:
3615
3616 public:
3617 static constexpr auto value =
3623};
3624
3625template<typename T>
3627{
3628 private:
3629 using t_ref = typename std::add_lvalue_reference<T>::type;
3630
3633
3634 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3635 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3636 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3637 static constexpr auto is_iterator_begin =
3639
3640 public:
3641 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3642};
3643
3644template<typename R>
3645using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3646
3647template<typename T>
3649
3650// The following implementation of is_complete_type is taken from
3651// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3652// and is written by Xiang Fan who agreed to using it in this library.
3653
3654template<typename T, typename = void>
3655struct is_complete_type : std::false_type {};
3656
3657template<typename T>
3658struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3659
3660template<typename BasicJsonType, typename CompatibleObjectType,
3661 typename = void>
3662struct is_compatible_object_type_impl : std::false_type {};
3663
3664template<typename BasicJsonType, typename CompatibleObjectType>
3666 BasicJsonType, CompatibleObjectType,
3667 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3668 is_detected<key_type_t, CompatibleObjectType>::value >>
3669{
3670 using object_t = typename BasicJsonType::object_t;
3671
3672 // macOS's is_constructible does not play well with nonesuch...
3673 static constexpr bool value =
3674 is_constructible<typename object_t::key_type,
3675 typename CompatibleObjectType::key_type>::value &&
3676 is_constructible<typename object_t::mapped_type,
3677 typename CompatibleObjectType::mapped_type>::value;
3678};
3679
3680template<typename BasicJsonType, typename CompatibleObjectType>
3682 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3683
3684template<typename BasicJsonType, typename ConstructibleObjectType,
3685 typename = void>
3686struct is_constructible_object_type_impl : std::false_type {};
3687
3688template<typename BasicJsonType, typename ConstructibleObjectType>
3690 BasicJsonType, ConstructibleObjectType,
3691 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3692 is_detected<key_type_t, ConstructibleObjectType>::value >>
3693{
3694 using object_t = typename BasicJsonType::object_t;
3695
3696 static constexpr bool value =
3698 (std::is_move_assignable<ConstructibleObjectType>::value ||
3699 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3700 (is_constructible<typename ConstructibleObjectType::key_type,
3701 typename object_t::key_type>::value &&
3702 std::is_same <
3703 typename object_t::mapped_type,
3704 typename ConstructibleObjectType::mapped_type >::value)) ||
3705 (has_from_json<BasicJsonType,
3706 typename ConstructibleObjectType::mapped_type>::value ||
3708 BasicJsonType,
3709 typename ConstructibleObjectType::mapped_type >::value);
3710};
3711
3712template<typename BasicJsonType, typename ConstructibleObjectType>
3714 : is_constructible_object_type_impl<BasicJsonType,
3715 ConstructibleObjectType> {};
3716
3717template<typename BasicJsonType, typename CompatibleStringType>
3719{
3720 static constexpr auto value =
3722};
3723
3724template<typename BasicJsonType, typename ConstructibleStringType>
3726{
3727 // launder type through decltype() to fix compilation failure on ICPC
3728#ifdef __INTEL_COMPILER
3729 using laundered_type = decltype(std::declval<ConstructibleStringType>());
3730#else
3731 using laundered_type = ConstructibleStringType;
3732#endif
3733
3734 static constexpr auto value =
3735 conjunction <
3737 is_detected_exact<typename BasicJsonType::string_t::value_type,
3739};
3740
3741template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3742struct is_compatible_array_type_impl : std::false_type {};
3743
3744template<typename BasicJsonType, typename CompatibleArrayType>
3746 BasicJsonType, CompatibleArrayType,
3747 enable_if_t <
3748 is_detected<iterator_t, CompatibleArrayType>::value&&
3749 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3750// special case for types like std::filesystem::path whose iterator's value_type are themselves
3751// c.f. https://github.com/nlohmann/json/pull/3073
3752 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3753{
3754 static constexpr bool value =
3755 is_constructible<BasicJsonType,
3757};
3758
3759template<typename BasicJsonType, typename CompatibleArrayType>
3761 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3762
3763template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3764struct is_constructible_array_type_impl : std::false_type {};
3765
3766template<typename BasicJsonType, typename ConstructibleArrayType>
3768 BasicJsonType, ConstructibleArrayType,
3769 enable_if_t<std::is_same<ConstructibleArrayType,
3770 typename BasicJsonType::value_type>::value >>
3771 : std::true_type {};
3772
3773template<typename BasicJsonType, typename ConstructibleArrayType>
3775 BasicJsonType, ConstructibleArrayType,
3776 enable_if_t < !std::is_same<ConstructibleArrayType,
3777 typename BasicJsonType::value_type>::value&&
3778 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3779 is_default_constructible<ConstructibleArrayType>::value&&
3780(std::is_move_assignable<ConstructibleArrayType>::value ||
3781 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3782is_detected<iterator_t, ConstructibleArrayType>::value&&
3783is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3784is_detected<range_value_t, ConstructibleArrayType>::value&&
3785// special case for types like std::filesystem::path whose iterator's value_type are themselves
3786// c.f. https://github.com/nlohmann/json/pull/3073
3787!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3789 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3790{
3792
3793 static constexpr bool value =
3794 std::is_same<value_type,
3795 typename BasicJsonType::array_t::value_type>::value ||
3796 has_from_json<BasicJsonType,
3797 value_type>::value ||
3799 BasicJsonType,
3800 value_type >::value;
3801};
3802
3803template<typename BasicJsonType, typename ConstructibleArrayType>
3805 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3806
3807template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3808 typename = void>
3809struct is_compatible_integer_type_impl : std::false_type {};
3810
3811template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3813 RealIntegerType, CompatibleNumberIntegerType,
3814 enable_if_t < std::is_integral<RealIntegerType>::value&&
3815 std::is_integral<CompatibleNumberIntegerType>::value&&
3816 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3817{
3818 // is there an assert somewhere on overflows?
3819 using RealLimits = std::numeric_limits<RealIntegerType>;
3820 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3821
3822 static constexpr auto value =
3823 is_constructible<RealIntegerType,
3824 CompatibleNumberIntegerType>::value &&
3825 CompatibleLimits::is_integer &&
3826 RealLimits::is_signed == CompatibleLimits::is_signed;
3827};
3828
3829template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3831 : is_compatible_integer_type_impl<RealIntegerType,
3832 CompatibleNumberIntegerType> {};
3833
3834template<typename BasicJsonType, typename CompatibleType, typename = void>
3835struct is_compatible_type_impl: std::false_type {};
3836
3837template<typename BasicJsonType, typename CompatibleType>
3839 BasicJsonType, CompatibleType,
3840 enable_if_t<is_complete_type<CompatibleType>::value >>
3841{
3842 static constexpr bool value =
3844};
3845
3846template<typename BasicJsonType, typename CompatibleType>
3848 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3849
3850template<typename T1, typename T2>
3851struct is_constructible_tuple : std::false_type {};
3852
3853template<typename T1, typename... Args>
3854struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3855
3856template<typename BasicJsonType, typename T>
3857struct is_json_iterator_of : std::false_type {};
3858
3859template<typename BasicJsonType>
3860struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3861
3862template<typename BasicJsonType>
3863struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3864{};
3865
3866// checks if a given type T is a template specialization of Primary
3867template<template <typename...> class Primary, typename T>
3868struct is_specialization_of : std::false_type {};
3869
3870template<template <typename...> class Primary, typename... Args>
3871struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3872
3873template<typename T>
3875
3876// checks if A and B are comparable using Compare functor
3877template<typename Compare, typename A, typename B, typename = void>
3878struct is_comparable : std::false_type {};
3879
3880template<typename Compare, typename A, typename B>
3881struct is_comparable<Compare, A, B, void_t<
3882decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3883decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3884>> : std::true_type {};
3885
3886template<typename T>
3887using detect_is_transparent = typename T::is_transparent;
3888
3889// type trait to check if KeyType can be used as object key (without a BasicJsonType)
3890// see is_usable_as_basic_json_key_type below
3891template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3892 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3893using is_usable_as_key_type = typename std::conditional <
3895 && !(ExcludeObjectKeyType && std::is_same<KeyType,
3896 ObjectKeyType>::value)
3897 && (!RequireTransparentComparator
3900 std::true_type,
3901 std::false_type >::type;
3902
3903// type trait to check if KeyType can be used as object key
3904// true if:
3905// - KeyType is comparable with BasicJsonType::object_t::key_type
3906// - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3907// - the comparator is transparent or RequireTransparentComparator is false
3908// - KeyType is not a JSON iterator or json_pointer
3909template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3910 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3911using is_usable_as_basic_json_key_type = typename std::conditional <
3912 is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
3913 typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
3914 RequireTransparentComparator, ExcludeObjectKeyType>::value
3916 std::true_type,
3917 std::false_type >::type;
3918
3919template<typename ObjectType, typename KeyType>
3920using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3921
3922// type trait to check if object_t has an erase() member functions accepting KeyType
3923template<typename BasicJsonType, typename KeyType>
3924using has_erase_with_key_type = typename std::conditional <
3925 is_detected <
3927 typename BasicJsonType::object_t, KeyType >::value,
3928 std::true_type,
3929 std::false_type >::type;
3930
3931// a naive helper to check if a type is an ordered_map (exploits the fact that
3932// ordered_map inherits capacity() from std::vector)
3933template <typename T>
3935{
3936 using one = char;
3937
3938 struct two
3939 {
3940 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3941 };
3942
3943 template <typename C> static one test( decltype(&C::capacity) ) ;
3944 template <typename C> static two test(...);
3945
3946 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3947};
3948
3949// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3950template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3952{
3953 return static_cast<T>(value);
3954}
3955
3956template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3957T conditional_static_cast(U value)
3958{
3959 return value;
3960}
3961
3962template<typename... Types>
3964
3965template<typename... Types>
3967
3968template<typename... Types>
3970
3971// there's a disjunction trait in another PR; replace when merged
3972template<typename... Types>
3973using same_sign = std::integral_constant < bool,
3974 all_signed<Types...>::value || all_unsigned<Types...>::value >;
3975
3976template<typename OfType, typename T>
3977using never_out_of_range = std::integral_constant < bool,
3978 (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
3979 || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
3980
3981template<typename OfType, typename T,
3982 bool OfTypeSigned = std::is_signed<OfType>::value,
3983 bool TSigned = std::is_signed<T>::value>
3985
3986template<typename OfType, typename T>
3987struct value_in_range_of_impl2<OfType, T, false, false>
3988{
3989 static constexpr bool test(T val)
3990 {
3991 using CommonType = typename std::common_type<OfType, T>::type;
3992 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
3993 }
3994};
3995
3996template<typename OfType, typename T>
3997struct value_in_range_of_impl2<OfType, T, true, false>
3998{
3999 static constexpr bool test(T val)
4000 {
4001 using CommonType = typename std::common_type<OfType, T>::type;
4002 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4003 }
4004};
4005
4006template<typename OfType, typename T>
4007struct value_in_range_of_impl2<OfType, T, false, true>
4008{
4009 static constexpr bool test(T val)
4010 {
4011 using CommonType = typename std::common_type<OfType, T>::type;
4012 return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4013 }
4014};
4015
4016
4017template<typename OfType, typename T>
4018struct value_in_range_of_impl2<OfType, T, true, true>
4019{
4020 static constexpr bool test(T val)
4021 {
4022 using CommonType = typename std::common_type<OfType, T>::type;
4023 return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4024 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4025 }
4026};
4027
4028template<typename OfType, typename T,
4029 bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4032
4033template<typename OfType, typename T>
4034struct value_in_range_of_impl1<OfType, T, false>
4035{
4036 static constexpr bool test(T val)
4037 {
4039 }
4040};
4041
4042template<typename OfType, typename T>
4043struct value_in_range_of_impl1<OfType, T, true>
4044{
4045 static constexpr bool test(T /*val*/)
4046 {
4047 return true;
4048 }
4049};
4050
4051template<typename OfType, typename T>
4052inline constexpr bool value_in_range_of(T val)
4053{
4055}
4056
4057} // namespace detail
4059
4060// #include <nlohmann/detail/string_concat.hpp>
4061// __ _____ _____ _____
4062// __| | __| | | | JSON for Modern C++
4063// | | |__ | | | | | | version 3.11.1
4064// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4065//
4066// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4067// SPDX-License-Identifier: MIT
4068
4069
4070
4071#include <cstring> // strlen
4072#include <string> // string
4073#include <utility> // forward
4074
4075// #include <nlohmann/detail/meta/cpp_future.hpp>
4076
4077// #include <nlohmann/detail/meta/detected.hpp>
4078
4079
4081namespace detail
4082{
4083
4084inline std::size_t concat_length()
4085{
4086 return 0;
4087}
4088
4089template<typename... Args>
4090inline std::size_t concat_length(const char* cstr, Args&& ... rest);
4091
4092template<typename StringType, typename... Args>
4093inline std::size_t concat_length(const StringType& str, Args&& ... rest);
4094
4095template<typename... Args>
4096inline std::size_t concat_length(const char /*c*/, Args&& ... rest)
4097{
4098 return 1 + concat_length(std::forward<Args>(rest)...);
4099}
4100
4101template<typename... Args>
4102inline std::size_t concat_length(const char* cstr, Args&& ... rest)
4103{
4104 // cppcheck-suppress ignoredReturnValue
4105 return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...);
4106}
4107
4108template<typename StringType, typename... Args>
4109inline std::size_t concat_length(const StringType& str, Args&& ... rest)
4110{
4111 return str.size() + concat_length(std::forward<Args>(rest)...);
4112}
4113
4114template<typename OutStringType>
4115inline void concat_into(OutStringType& /*out*/)
4116{}
4117
4118template<typename StringType, typename Arg>
4119using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
4120
4121template<typename StringType, typename Arg>
4123
4124template<typename StringType, typename Arg>
4125using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
4126
4127template<typename StringType, typename Arg>
4129
4130template<typename StringType, typename Arg>
4131using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4132
4133template<typename StringType, typename Arg>
4135
4136template<typename StringType, typename Arg>
4137using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4138
4139template<typename StringType, typename Arg>
4141
4142template < typename OutStringType, typename Arg, typename... Args,
4145inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
4146
4147template < typename OutStringType, typename Arg, typename... Args,
4151inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4152
4153template < typename OutStringType, typename Arg, typename... Args,
4158inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4159
4160template<typename OutStringType, typename Arg, typename... Args,
4162inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
4163{
4164 out.append(std::forward<Arg>(arg));
4165 concat_into(out, std::forward<Args>(rest)...);
4166}
4167
4168template < typename OutStringType, typename Arg, typename... Args,
4169 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4170 && detect_string_can_append_op<OutStringType, Arg>::value, int > >
4171inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4172{
4173 out += std::forward<Arg>(arg);
4174 concat_into(out, std::forward<Args>(rest)...);
4175}
4176
4177template < typename OutStringType, typename Arg, typename... Args,
4178 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4179 && !detect_string_can_append_op<OutStringType, Arg>::value
4180 && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
4181inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4182{
4183 out.append(arg.begin(), arg.end());
4184 concat_into(out, std::forward<Args>(rest)...);
4185}
4186
4187template < typename OutStringType, typename Arg, typename... Args,
4188 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4189 && !detect_string_can_append_op<OutStringType, Arg>::value
4190 && !detect_string_can_append_iter<OutStringType, Arg>::value
4191 && detect_string_can_append_data<OutStringType, Arg>::value, int > >
4192inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4193{
4194 out.append(arg.data(), arg.size());
4195 concat_into(out, std::forward<Args>(rest)...);
4196}
4197
4198template<typename OutStringType = std::string, typename... Args>
4199inline OutStringType concat(Args && ... args)
4200{
4201 OutStringType str;
4202 str.reserve(concat_length(std::forward<Args>(args)...));
4203 concat_into(str, std::forward<Args>(args)...);
4204 return str;
4205}
4206
4207} // namespace detail
4209
4210
4211
4213namespace detail
4214{
4215
4217// exceptions //
4219
4222class exception : public std::exception
4223{
4224 public:
4226 const char* what() const noexcept override
4227 {
4228 return m.what();
4229 }
4230
4232 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4233
4234 protected:
4236 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4237
4238 static std::string name(const std::string& ename, int id_)
4239 {
4240 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4241 }
4242
4243 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4244 {
4245 return "";
4246 }
4247
4248 template<typename BasicJsonType>
4249 static std::string diagnostics(const BasicJsonType* leaf_element)
4250 {
4251#if JSON_DIAGNOSTICS
4252 std::vector<std::string> tokens;
4253 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4254 {
4255 switch (current->m_parent->type())
4256 {
4257 case value_t::array:
4258 {
4259 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
4260 {
4261 if (&current->m_parent->m_value.array->operator[](i) == current)
4262 {
4263 tokens.emplace_back(std::to_string(i));
4264 break;
4265 }
4266 }
4267 break;
4268 }
4269
4270 case value_t::object:
4271 {
4272 for (const auto& element : *current->m_parent->m_value.object)
4273 {
4274 if (&element.second == current)
4275 {
4276 tokens.emplace_back(element.first.c_str());
4277 break;
4278 }
4279 }
4280 break;
4281 }
4282
4283 case value_t::null: // LCOV_EXCL_LINE
4284 case value_t::string: // LCOV_EXCL_LINE
4285 case value_t::boolean: // LCOV_EXCL_LINE
4286 case value_t::number_integer: // LCOV_EXCL_LINE
4287 case value_t::number_unsigned: // LCOV_EXCL_LINE
4288 case value_t::number_float: // LCOV_EXCL_LINE
4289 case value_t::binary: // LCOV_EXCL_LINE
4290 case value_t::discarded: // LCOV_EXCL_LINE
4291 default: // LCOV_EXCL_LINE
4292 break; // LCOV_EXCL_LINE
4293 }
4294 }
4295
4296 if (tokens.empty())
4297 {
4298 return "";
4299 }
4300
4301 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4302 [](const std::string & a, const std::string & b)
4303 {
4304 return concat(a, '/', detail::escape(b));
4305 });
4306 return concat('(', str, ") ");
4307#else
4308 static_cast<void>(leaf_element);
4309 return "";
4310#endif
4311 }
4312
4313 private:
4315 std::runtime_error m;
4316};
4317
4321{
4322 public:
4332 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4333 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4334 {
4335 std::string w = concat(exception::name("parse_error", id_), "parse error",
4336 position_string(pos), ": ", exception::diagnostics(context), what_arg);
4337 return {id_, pos.chars_read_total, w.c_str()};
4338 }
4339
4340 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4341 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4342 {
4343 std::string w = concat(exception::name("parse_error", id_), "parse error",
4344 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4345 ": ", exception::diagnostics(context), what_arg);
4346 return {id_, byte_, w.c_str()};
4347 }
4348
4358 const std::size_t byte;
4359
4360 private:
4361 parse_error(int id_, std::size_t byte_, const char* what_arg)
4362 : exception(id_, what_arg), byte(byte_) {}
4363
4364 static std::string position_string(const position_t& pos)
4365 {
4366 return concat(" at line ", std::to_string(pos.lines_read + 1),
4367 ", column ", std::to_string(pos.chars_read_current_line));
4368 }
4369};
4370
4374{
4375 public:
4376 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4377 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4378 {
4379 std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4380 return {id_, w.c_str()};
4381 }
4382
4383 private:
4385 invalid_iterator(int id_, const char* what_arg)
4386 : exception(id_, what_arg) {}
4387};
4388
4391class type_error : public exception
4392{
4393 public:
4394 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4395 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4396 {
4397 std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4398 return {id_, w.c_str()};
4399 }
4400
4401 private:
4403 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4404};
4405
4409{
4410 public:
4411 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4412 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4413 {
4414 std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4415 return {id_, w.c_str()};
4416 }
4417
4418 private:
4420 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4421};
4422
4426{
4427 public:
4428 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4429 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4430 {
4431 std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4432 return {id_, w.c_str()};
4433 }
4434
4435 private:
4437 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4438};
4439
4440} // namespace detail
4442
4443// #include <nlohmann/detail/macro_scope.hpp>
4444
4445// #include <nlohmann/detail/meta/cpp_future.hpp>
4446
4447// #include <nlohmann/detail/meta/identity_tag.hpp>
4448// __ _____ _____ _____
4449// __| | __| | | | JSON for Modern C++
4450// | | |__ | | | | | | version 3.11.1
4451// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4452//
4453// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4454// SPDX-License-Identifier: MIT
4455
4456
4457
4458// #include <nlohmann/detail/abi_macros.hpp>
4459
4460
4462namespace detail
4463{
4464
4465// dispatching helper struct
4466template <class T> struct identity_tag {};
4467
4468} // namespace detail
4470
4471// #include <nlohmann/detail/meta/std_fs.hpp>
4472// __ _____ _____ _____
4473// __| | __| | | | JSON for Modern C++
4474// | | |__ | | | | | | version 3.11.1
4475// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4476//
4477// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4478// SPDX-License-Identifier: MIT
4479
4480
4481
4482// #include <nlohmann/detail/macro_scope.hpp>
4483
4484
4485#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4486#include <experimental/filesystem>
4488namespace detail
4489{
4490namespace std_fs = std::experimental::filesystem;
4491} // namespace detail
4493#elif JSON_HAS_FILESYSTEM
4494#include <filesystem>
4496namespace detail
4497{
4498namespace std_fs = std::filesystem;
4499} // namespace detail
4501#endif
4502
4503// #include <nlohmann/detail/meta/type_traits.hpp>
4504
4505// #include <nlohmann/detail/string_concat.hpp>
4506
4507// #include <nlohmann/detail/value_t.hpp>
4508
4509
4511namespace detail
4512{
4513
4514template<typename BasicJsonType>
4515inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4516{
4517 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4518 {
4519 JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4520 }
4521 n = nullptr;
4522}
4523
4524// overloads for basic_json template parameters
4525template < typename BasicJsonType, typename ArithmeticType,
4526 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
4527 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4528 int > = 0 >
4529void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4530{
4531 switch (static_cast<value_t>(j))
4532 {
4534 {
4535 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4536 break;
4537 }
4539 {
4540 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4541 break;
4542 }
4544 {
4545 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4546 break;
4547 }
4548
4549 case value_t::null:
4550 case value_t::object:
4551 case value_t::array:
4552 case value_t::string:
4553 case value_t::boolean:
4554 case value_t::binary:
4555 case value_t::discarded:
4556 default:
4557 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4558 }
4559}
4560
4561template<typename BasicJsonType>
4562inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4563{
4564 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4565 {
4566 JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4567 }
4568 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4569}
4570
4571template<typename BasicJsonType>
4572inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4573{
4574 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4575 {
4576 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4577 }
4578 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4579}
4580
4581template <
4582 typename BasicJsonType, typename StringType,
4583 enable_if_t <
4584 std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4585 && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
4586 && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4587 && !is_json_ref<StringType>::value, int > = 0 >
4588inline void from_json(const BasicJsonType& j, StringType& s)
4589{
4590 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4591 {
4592 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4593 }
4594
4595 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4596}
4597
4598template<typename BasicJsonType>
4599inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4600{
4601 get_arithmetic_value(j, val);
4602}
4603
4604template<typename BasicJsonType>
4605inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4606{
4607 get_arithmetic_value(j, val);
4608}
4609
4610template<typename BasicJsonType>
4611inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4612{
4613 get_arithmetic_value(j, val);
4614}
4615
4616#if !JSON_DISABLE_ENUM_SERIALIZATION
4617template<typename BasicJsonType, typename EnumType,
4618 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4619inline void from_json(const BasicJsonType& j, EnumType& e)
4620{
4621 typename std::underlying_type<EnumType>::type val;
4622 get_arithmetic_value(j, val);
4623 e = static_cast<EnumType>(val);
4624}
4625#endif // JSON_DISABLE_ENUM_SERIALIZATION
4626
4627// forward_list doesn't have an insert method
4628template<typename BasicJsonType, typename T, typename Allocator,
4629 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4630inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4631{
4632 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4633 {
4634 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4635 }
4636 l.clear();
4637 std::transform(j.rbegin(), j.rend(),
4638 std::front_inserter(l), [](const BasicJsonType & i)
4639 {
4640 return i.template get<T>();
4641 });
4642}
4643
4644// valarray doesn't have an insert method
4645template<typename BasicJsonType, typename T,
4646 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4647inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4648{
4649 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4650 {
4651 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4652 }
4653 l.resize(j.size());
4654 std::transform(j.begin(), j.end(), std::begin(l),
4655 [](const BasicJsonType & elem)
4656 {
4657 return elem.template get<T>();
4658 });
4659}
4660
4661template<typename BasicJsonType, typename T, std::size_t N>
4662auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4663-> decltype(j.template get<T>(), void())
4664{
4665 for (std::size_t i = 0; i < N; ++i)
4666 {
4667 arr[i] = j.at(i).template get<T>();
4668 }
4669}
4670
4671template<typename BasicJsonType>
4672inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4673{
4674 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4675}
4676
4677template<typename BasicJsonType, typename T, std::size_t N>
4678auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4679 priority_tag<2> /*unused*/)
4680-> decltype(j.template get<T>(), void())
4681{
4682 for (std::size_t i = 0; i < N; ++i)
4683 {
4684 arr[i] = j.at(i).template get<T>();
4685 }
4686}
4687
4688template<typename BasicJsonType, typename ConstructibleArrayType,
4690 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4691 int> = 0>
4692auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4693-> decltype(
4694 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4695 j.template get<typename ConstructibleArrayType::value_type>(),
4696 void())
4697{
4698 using std::end;
4699
4700 ConstructibleArrayType ret;
4701 ret.reserve(j.size());
4702 std::transform(j.begin(), j.end(),
4703 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4704 {
4705 // get<BasicJsonType>() returns *this, this won't call a from_json
4706 // method when value_type is BasicJsonType
4707 return i.template get<typename ConstructibleArrayType::value_type>();
4708 });
4709 arr = std::move(ret);
4710}
4711
4712template<typename BasicJsonType, typename ConstructibleArrayType,
4714 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4715 int> = 0>
4716inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4717 priority_tag<0> /*unused*/)
4718{
4719 using std::end;
4720
4721 ConstructibleArrayType ret;
4722 std::transform(
4723 j.begin(), j.end(), std::inserter(ret, end(ret)),
4724 [](const BasicJsonType & i)
4725 {
4726 // get<BasicJsonType>() returns *this, this won't call a from_json
4727 // method when value_type is BasicJsonType
4728 return i.template get<typename ConstructibleArrayType::value_type>();
4729 });
4730 arr = std::move(ret);
4731}
4732
4733template < typename BasicJsonType, typename ConstructibleArrayType,
4734 enable_if_t <
4735 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4736 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4738 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4739 !is_basic_json<ConstructibleArrayType>::value,
4740 int > = 0 >
4741auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4742-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4743j.template get<typename ConstructibleArrayType::value_type>(),
4744void())
4745{
4746 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4747 {
4748 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4749 }
4750
4751 from_json_array_impl(j, arr, priority_tag<3> {});
4752}
4753
4754template < typename BasicJsonType, typename T, std::size_t... Idx >
4755std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4756 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4757{
4758 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4759}
4760
4761template < typename BasicJsonType, typename T, std::size_t N >
4762auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4763-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4764{
4765 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4766 {
4767 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4768 }
4769
4770 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4771}
4772
4773template<typename BasicJsonType>
4774inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4775{
4776 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4777 {
4778 JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4779 }
4780
4781 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4782}
4783
4784template<typename BasicJsonType, typename ConstructibleObjectType,
4785 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4786inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4787{
4788 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4789 {
4790 JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4791 }
4792
4793 ConstructibleObjectType ret;
4794 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4795 using value_type = typename ConstructibleObjectType::value_type;
4796 std::transform(
4797 inner_object->begin(), inner_object->end(),
4798 std::inserter(ret, ret.begin()),
4799 [](typename BasicJsonType::object_t::value_type const & p)
4800 {
4801 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4802 });
4803 obj = std::move(ret);
4804}
4805
4806// overload for arithmetic types, not chosen for basic_json template arguments
4807// (BooleanType, etc..); note: Is it really necessary to provide explicit
4808// overloads for boolean_t etc. in case of a custom BooleanType which is not
4809// an arithmetic type?
4810template < typename BasicJsonType, typename ArithmeticType,
4811 enable_if_t <
4812 std::is_arithmetic<ArithmeticType>::value&&
4813 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4814 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4815 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4816 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4817 int > = 0 >
4818inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4819{
4820 switch (static_cast<value_t>(j))
4821 {
4823 {
4824 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4825 break;
4826 }
4828 {
4829 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4830 break;
4831 }
4833 {
4834 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4835 break;
4836 }
4837 case value_t::boolean:
4838 {
4839 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4840 break;
4841 }
4842
4843 case value_t::null:
4844 case value_t::object:
4845 case value_t::array:
4846 case value_t::string:
4847 case value_t::binary:
4848 case value_t::discarded:
4849 default:
4850 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4851 }
4852}
4853
4854template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4855std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4856{
4857 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4858}
4859
4860template < typename BasicJsonType, class A1, class A2 >
4861std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4862{
4863 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4864 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4865}
4866
4867template<typename BasicJsonType, typename A1, typename A2>
4868inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4869{
4870 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4871}
4872
4873template<typename BasicJsonType, typename... Args>
4874std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4875{
4876 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4877}
4878
4879template<typename BasicJsonType, typename... Args>
4880inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4881{
4882 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4883}
4884
4885template<typename BasicJsonType, typename TupleRelated>
4886auto from_json(BasicJsonType&& j, TupleRelated&& t)
4887-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4888{
4889 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4890 {
4891 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4892 }
4893
4894 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4895}
4896
4897template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4898 typename = enable_if_t < !std::is_constructible <
4899 typename BasicJsonType::string_t, Key >::value >>
4900inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4901{
4902 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4903 {
4904 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4905 }
4906 m.clear();
4907 for (const auto& p : j)
4908 {
4909 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4910 {
4911 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4912 }
4913 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4914 }
4915}
4916
4917template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4918 typename = enable_if_t < !std::is_constructible <
4919 typename BasicJsonType::string_t, Key >::value >>
4920inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4921{
4922 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4923 {
4924 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4925 }
4926 m.clear();
4927 for (const auto& p : j)
4928 {
4929 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4930 {
4931 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4932 }
4933 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4934 }
4935}
4936
4937#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
4938template<typename BasicJsonType>
4939inline void from_json(const BasicJsonType& j, std_fs::path& p)
4940{
4941 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4942 {
4943 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4944 }
4945 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4946}
4947#endif
4948
4950{
4951 template<typename BasicJsonType, typename T>
4952 auto operator()(const BasicJsonType& j, T&& val) const
4953 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4954 -> decltype(from_json(j, std::forward<T>(val)))
4955 {
4956 return from_json(j, std::forward<T>(val));
4957 }
4958};
4959
4960} // namespace detail
4961
4962#ifndef JSON_HAS_CPP_17
4966namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4967{
4968#endif
4969JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
4971#ifndef JSON_HAS_CPP_17
4972} // namespace
4973#endif
4974
4976
4977// #include <nlohmann/detail/conversions/to_json.hpp>
4978// __ _____ _____ _____
4979// __| | __| | | | JSON for Modern C++
4980// | | |__ | | | | | | version 3.11.1
4981// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4982//
4983// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4984// SPDX-License-Identifier: MIT
4985
4986
4987
4988#include <algorithm> // copy
4989#include <iterator> // begin, end
4990#include <string> // string
4991#include <tuple> // tuple, get
4992#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4993#include <utility> // move, forward, declval, pair
4994#include <valarray> // valarray
4995#include <vector> // vector
4996
4997// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4998// __ _____ _____ _____
4999// __| | __| | | | JSON for Modern C++
5000// | | |__ | | | | | | version 3.11.1
5001// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5002//
5003// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5004// SPDX-License-Identifier: MIT
5005
5006
5007
5008#include <cstddef> // size_t
5009#include <iterator> // input_iterator_tag
5010#include <string> // string, to_string
5011#include <tuple> // tuple_size, get, tuple_element
5012#include <utility> // move
5013
5014#if JSON_HAS_RANGES
5015 #include <ranges> // enable_borrowed_range
5016#endif
5017
5018// #include <nlohmann/detail/abi_macros.hpp>
5019
5020// #include <nlohmann/detail/meta/type_traits.hpp>
5021
5022// #include <nlohmann/detail/value_t.hpp>
5023
5024
5026namespace detail
5027{
5028
5029template<typename string_type>
5030void int_to_string( string_type& target, std::size_t value )
5031{
5032 // For ADL
5033 using std::to_string;
5034 target = to_string(value);
5035}
5036template<typename IteratorType> class iteration_proxy_value
5037{
5038 public:
5039 using difference_type = std::ptrdiff_t;
5043 using iterator_category = std::input_iterator_tag;
5044 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
5045
5046 private:
5048 IteratorType anchor{};
5050 std::size_t array_index = 0;
5052 mutable std::size_t array_index_last = 0;
5057
5058 public:
5059 explicit iteration_proxy_value() = default;
5060 explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5061 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5062 && std::is_nothrow_default_constructible<string_type>::value)
5063 : anchor(std::move(it))
5064 , array_index(array_index_)
5065 {}
5066
5069 // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5071 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5072 && std::is_nothrow_move_constructible<string_type>::value) = default;
5074 noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5075 && std::is_nothrow_move_assignable<string_type>::value) = default;
5077
5079 const iteration_proxy_value& operator*() const
5080 {
5081 return *this;
5082 }
5083
5086 {
5087 ++anchor;
5088 ++array_index;
5089
5090 return *this;
5091 }
5092
5093 iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5094 {
5096 ++anchor;
5097 ++array_index;
5098 return tmp;
5099 }
5100
5103 {
5104 return anchor == o.anchor;
5105 }
5106
5109 {
5110 return anchor != o.anchor;
5111 }
5112
5114 const string_type& key() const
5115 {
5116 JSON_ASSERT(anchor.m_object != nullptr);
5117
5118 switch (anchor.m_object->type())
5119 {
5120 // use integer array index as key
5121 case value_t::array:
5122 {
5124 {
5127 }
5128 return array_index_str;
5129 }
5130
5131 // use key from the object
5132 case value_t::object:
5133 return anchor.key();
5134
5135 // use an empty key for all primitive types
5136 case value_t::null:
5137 case value_t::string:
5138 case value_t::boolean:
5142 case value_t::binary:
5143 case value_t::discarded:
5144 default:
5145 return empty_str;
5146 }
5147 }
5148
5150 typename IteratorType::reference value() const
5151 {
5152 return anchor.value();
5153 }
5154};
5155
5157template<typename IteratorType> class iteration_proxy
5158{
5159 private:
5161 typename IteratorType::pointer container = nullptr;
5162
5163 public:
5164 explicit iteration_proxy() = default;
5165
5167 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5168 : container(&cont) {}
5169
5172 iteration_proxy(iteration_proxy&&) noexcept = default;
5173 iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5174 ~iteration_proxy() = default;
5175
5177 iteration_proxy_value<IteratorType> begin() const noexcept
5178 {
5180 }
5181
5184 {
5186 }
5187};
5188
5189// Structured Bindings Support
5190// For further reference see https://blog.tartanllama.xyz/structured-bindings/
5191// And see https://github.com/nlohmann/json/pull/1391
5192template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5193auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5194{
5195 return i.key();
5196}
5197// Structured Bindings Support
5198// For further reference see https://blog.tartanllama.xyz/structured-bindings/
5199// And see https://github.com/nlohmann/json/pull/1391
5200template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5201auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5202{
5203 return i.value();
5204}
5205
5206} // namespace detail
5208
5209// The Addition to the STD Namespace is required to add
5210// Structured Bindings Support to the iteration_proxy_value class
5211// For further reference see https://blog.tartanllama.xyz/structured-bindings/
5212// And see https://github.com/nlohmann/json/pull/1391
5213namespace std
5214{
5215
5216#if defined(__clang__)
5217 // Fix: https://github.com/nlohmann/json/issues/1401
5218 #pragma clang diagnostic push
5219 #pragma clang diagnostic ignored "-Wmismatched-tags"
5220#endif
5221template<typename IteratorType>
5222class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
5223 : public std::integral_constant<std::size_t, 2> {};
5224
5225template<std::size_t N, typename IteratorType>
5226class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
5227{
5228 public:
5229 using type = decltype(
5230 get<N>(std::declval <
5231 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5232};
5233#if defined(__clang__)
5234 #pragma clang diagnostic pop
5235#endif
5236
5237} // namespace std
5238
5239#if JSON_HAS_RANGES
5240 template <typename IteratorType>
5241 inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5242#endif
5243
5244// #include <nlohmann/detail/macro_scope.hpp>
5245
5246// #include <nlohmann/detail/meta/cpp_future.hpp>
5247
5248// #include <nlohmann/detail/meta/std_fs.hpp>
5249
5250// #include <nlohmann/detail/meta/type_traits.hpp>
5251
5252// #include <nlohmann/detail/value_t.hpp>
5253
5254
5256namespace detail
5257{
5258
5260// constructors //
5262
5263/*
5264 * Note all external_constructor<>::construct functions need to call
5265 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
5266 * allocated value (e.g., a string). See bug issue
5267 * https://github.com/nlohmann/json/issues/2865 for more information.
5268 */
5269
5270template<value_t> struct external_constructor;
5271
5272template<>
5274{
5275 template<typename BasicJsonType>
5276 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5277 {
5278 j.m_value.destroy(j.m_type);
5279 j.m_type = value_t::boolean;
5280 j.m_value = b;
5281 j.assert_invariant();
5282 }
5283};
5284
5285template<>
5287{
5288 template<typename BasicJsonType>
5289 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5290 {
5291 j.m_value.destroy(j.m_type);
5292 j.m_type = value_t::string;
5293 j.m_value = s;
5294 j.assert_invariant();
5295 }
5296
5297 template<typename BasicJsonType>
5298 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5299 {
5300 j.m_value.destroy(j.m_type);
5301 j.m_type = value_t::string;
5302 j.m_value = std::move(s);
5303 j.assert_invariant();
5304 }
5305
5306 template < typename BasicJsonType, typename CompatibleStringType,
5308 int > = 0 >
5309 static void construct(BasicJsonType& j, const CompatibleStringType& str)
5310 {
5311 j.m_value.destroy(j.m_type);
5312 j.m_type = value_t::string;
5313 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5314 j.assert_invariant();
5315 }
5316};
5317
5318template<>
5320{
5321 template<typename BasicJsonType>
5322 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5323 {
5324 j.m_value.destroy(j.m_type);
5325 j.m_type = value_t::binary;
5326 j.m_value = typename BasicJsonType::binary_t(b);
5327 j.assert_invariant();
5328 }
5329
5330 template<typename BasicJsonType>
5331 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5332 {
5333 j.m_value.destroy(j.m_type);
5334 j.m_type = value_t::binary;
5335 j.m_value = typename BasicJsonType::binary_t(std::move(b));
5336 j.assert_invariant();
5337 }
5338};
5339
5340template<>
5342{
5343 template<typename BasicJsonType>
5344 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5345 {
5346 j.m_value.destroy(j.m_type);
5347 j.m_type = value_t::number_float;
5348 j.m_value = val;
5349 j.assert_invariant();
5350 }
5351};
5352
5353template<>
5355{
5356 template<typename BasicJsonType>
5357 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5358 {
5359 j.m_value.destroy(j.m_type);
5360 j.m_type = value_t::number_unsigned;
5361 j.m_value = val;
5362 j.assert_invariant();
5363 }
5364};
5365
5366template<>
5368{
5369 template<typename BasicJsonType>
5370 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5371 {
5372 j.m_value.destroy(j.m_type);
5373 j.m_type = value_t::number_integer;
5374 j.m_value = val;
5375 j.assert_invariant();
5376 }
5377};
5378
5379template<>
5381{
5382 template<typename BasicJsonType>
5383 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5384 {
5385 j.m_value.destroy(j.m_type);
5386 j.m_type = value_t::array;
5387 j.m_value = arr;
5388 j.set_parents();
5389 j.assert_invariant();
5390 }
5391
5392 template<typename BasicJsonType>
5393 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5394 {
5395 j.m_value.destroy(j.m_type);
5396 j.m_type = value_t::array;
5397 j.m_value = std::move(arr);
5398 j.set_parents();
5399 j.assert_invariant();
5400 }
5401
5402 template < typename BasicJsonType, typename CompatibleArrayType,
5404 int > = 0 >
5405 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5406 {
5407 using std::begin;
5408 using std::end;
5409
5410 j.m_value.destroy(j.m_type);
5411 j.m_type = value_t::array;
5412 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5413 j.set_parents();
5414 j.assert_invariant();
5415 }
5416
5417 template<typename BasicJsonType>
5418 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5419 {
5420 j.m_value.destroy(j.m_type);
5421 j.m_type = value_t::array;
5422 j.m_value = value_t::array;
5423 j.m_value.array->reserve(arr.size());
5424 for (const bool x : arr)
5425 {
5426 j.m_value.array->push_back(x);
5427 j.set_parent(j.m_value.array->back());
5428 }
5429 j.assert_invariant();
5430 }
5431
5432 template<typename BasicJsonType, typename T,
5434 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5435 {
5436 j.m_value.destroy(j.m_type);
5437 j.m_type = value_t::array;
5438 j.m_value = value_t::array;
5439 j.m_value.array->resize(arr.size());
5440 if (arr.size() > 0)
5441 {
5442 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
5443 }
5444 j.set_parents();
5445 j.assert_invariant();
5446 }
5447};
5448
5449template<>
5451{
5452 template<typename BasicJsonType>
5453 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5454 {
5455 j.m_value.destroy(j.m_type);
5456 j.m_type = value_t::object;
5457 j.m_value = obj;
5458 j.set_parents();
5459 j.assert_invariant();
5460 }
5461
5462 template<typename BasicJsonType>
5463 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5464 {
5465 j.m_value.destroy(j.m_type);
5466 j.m_type = value_t::object;
5467 j.m_value = std::move(obj);
5468 j.set_parents();
5469 j.assert_invariant();
5470 }
5471
5472 template < typename BasicJsonType, typename CompatibleObjectType,
5474 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5475 {
5476 using std::begin;
5477 using std::end;
5478
5479 j.m_value.destroy(j.m_type);
5480 j.m_type = value_t::object;
5481 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5482 j.set_parents();
5483 j.assert_invariant();
5484 }
5485};
5486
5488// to_json //
5490
5491template<typename BasicJsonType, typename T,
5492 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5493inline void to_json(BasicJsonType& j, T b) noexcept
5494{
5496}
5497
5498template<typename BasicJsonType,
5499 enable_if_t<std::is_convertible<const std::vector<bool>::reference&, typename BasicJsonType::boolean_t>::value, int> = 0>
5500inline void to_json(BasicJsonType& j, const std::vector<bool>::reference& b) noexcept
5501{
5502 external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5503}
5504
5505template<typename BasicJsonType, typename CompatibleString,
5506 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5507inline void to_json(BasicJsonType& j, const CompatibleString& s)
5508{
5510}
5511
5512template<typename BasicJsonType>
5513inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5514{
5516}
5517
5518template<typename BasicJsonType, typename FloatType,
5519 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5520inline void to_json(BasicJsonType& j, FloatType val) noexcept
5521{
5522 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5523}
5524
5525template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5526 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5527inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5528{
5529 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5530}
5531
5532template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5533 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5534inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5535{
5536 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5537}
5538
5539#if !JSON_DISABLE_ENUM_SERIALIZATION
5540template<typename BasicJsonType, typename EnumType,
5541 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5542inline void to_json(BasicJsonType& j, EnumType e) noexcept
5543{
5544 using underlying_type = typename std::underlying_type<EnumType>::type;
5545 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5546}
5547#endif // JSON_DISABLE_ENUM_SERIALIZATION
5548
5549template<typename BasicJsonType>
5550inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5551{
5553}
5554
5555template < typename BasicJsonType, typename CompatibleArrayType,
5556 enable_if_t < is_compatible_array_type<BasicJsonType,
5557 CompatibleArrayType>::value&&
5558 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
5560 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
5561 !is_basic_json<CompatibleArrayType>::value,
5562 int > = 0 >
5563inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5564{
5566}
5567
5568template<typename BasicJsonType>
5569inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5570{
5572}
5573
5574template<typename BasicJsonType, typename T,
5575 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5576inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5577{
5579}
5580
5581template<typename BasicJsonType>
5582inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5583{
5585}
5586
5587template < typename BasicJsonType, typename CompatibleObjectType,
5588 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5589inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5590{
5592}
5593
5594template<typename BasicJsonType>
5595inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5596{
5598}
5599
5600template <
5601 typename BasicJsonType, typename T, std::size_t N,
5602 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5603 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5604 int > = 0 >
5605inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5606{
5608}
5609
5610template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5611inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5612{
5613 j = { p.first, p.second };
5614}
5615
5616// for https://github.com/nlohmann/json/pull/1134
5617template<typename BasicJsonType, typename T,
5618 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5619inline void to_json(BasicJsonType& j, const T& b)
5620{
5621 j = { {b.key(), b.value()} };
5622}
5623
5624template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5625inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5626{
5627 j = { std::get<Idx>(t)... };
5628}
5629
5630template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5631inline void to_json(BasicJsonType& j, const T& t)
5632{
5633 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5634}
5635
5636#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5637template<typename BasicJsonType>
5638inline void to_json(BasicJsonType& j, const std_fs::path& p)
5639{
5640 j = p.string();
5641}
5642#endif
5643
5645{
5646 template<typename BasicJsonType, typename T>
5647 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5648 -> decltype(to_json(j, std::forward<T>(val)), void())
5649 {
5650 return to_json(j, std::forward<T>(val));
5651 }
5652};
5653} // namespace detail
5654
5655#ifndef JSON_HAS_CPP_17
5659namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5660{
5661#endif
5662JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5664#ifndef JSON_HAS_CPP_17
5665} // namespace
5666#endif
5667
5669
5670// #include <nlohmann/detail/meta/identity_tag.hpp>
5671
5672
5674
5676template<typename ValueType, typename>
5678{
5681 template<typename BasicJsonType, typename TargetType = ValueType>
5682 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5683 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5684 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5685 {
5686 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5687 }
5688
5691 template<typename BasicJsonType, typename TargetType = ValueType>
5692 static auto from_json(BasicJsonType && j) noexcept(
5693 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5694 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5695 {
5696 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5697 }
5698
5701 template<typename BasicJsonType, typename TargetType = ValueType>
5702 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5703 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5704 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5705 {
5706 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5707 }
5708};
5709
5711
5712// #include <nlohmann/byte_container_with_subtype.hpp>
5713// __ _____ _____ _____
5714// __| | __| | | | JSON for Modern C++
5715// | | |__ | | | | | | version 3.11.1
5716// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5717//
5718// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5719// SPDX-License-Identifier: MIT
5720
5721
5722
5723#include <cstdint> // uint8_t, uint64_t
5724#include <tuple> // tie
5725#include <utility> // move
5726
5727// #include <nlohmann/detail/abi_macros.hpp>
5728
5729
5731
5734template<typename BinaryType>
5735class byte_container_with_subtype : public BinaryType
5736{
5737 public:
5738 using container_type = BinaryType;
5739 using subtype_type = std::uint64_t;
5740
5743 : container_type()
5744 {}
5745
5748 : container_type(b)
5749 {}
5750
5752 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5753 : container_type(std::move(b))
5754 {}
5755
5758 : container_type(b)
5759 , m_subtype(subtype_)
5760 , m_has_subtype(true)
5761 {}
5762
5764 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5765 : container_type(std::move(b))
5766 , m_subtype(subtype_)
5767 , m_has_subtype(true)
5768 {}
5769
5771 {
5772 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5773 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5774 }
5775
5777 {
5778 return !(rhs == *this);
5779 }
5780
5783 void set_subtype(subtype_type subtype_) noexcept
5784 {
5785 m_subtype = subtype_;
5786 m_has_subtype = true;
5787 }
5788
5791 constexpr subtype_type subtype() const noexcept
5792 {
5793 return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5794 }
5795
5798 constexpr bool has_subtype() const noexcept
5799 {
5800 return m_has_subtype;
5801 }
5802
5805 void clear_subtype() noexcept
5806 {
5807 m_subtype = 0;
5808 m_has_subtype = false;
5809 }
5810
5811 private:
5813 bool m_has_subtype = false;
5814};
5815
5817
5818// #include <nlohmann/detail/conversions/from_json.hpp>
5819
5820// #include <nlohmann/detail/conversions/to_json.hpp>
5821
5822// #include <nlohmann/detail/exceptions.hpp>
5823
5824// #include <nlohmann/detail/hash.hpp>
5825// __ _____ _____ _____
5826// __| | __| | | | JSON for Modern C++
5827// | | |__ | | | | | | version 3.11.1
5828// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5829//
5830// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5831// SPDX-License-Identifier: MIT
5832
5833
5834
5835#include <cstdint> // uint8_t
5836#include <cstddef> // size_t
5837#include <functional> // hash
5838
5839// #include <nlohmann/detail/abi_macros.hpp>
5840
5841// #include <nlohmann/detail/value_t.hpp>
5842
5843
5845namespace detail
5846{
5847
5848// boost::hash_combine
5849inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5850{
5851 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5852 return seed;
5853}
5854
5866template<typename BasicJsonType>
5867std::size_t hash(const BasicJsonType& j)
5868{
5869 using string_t = typename BasicJsonType::string_t;
5870 using number_integer_t = typename BasicJsonType::number_integer_t;
5871 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5872 using number_float_t = typename BasicJsonType::number_float_t;
5873
5874 const auto type = static_cast<std::size_t>(j.type());
5875 switch (j.type())
5876 {
5877 case BasicJsonType::value_t::null:
5878 case BasicJsonType::value_t::discarded:
5879 {
5880 return combine(type, 0);
5881 }
5882
5883 case BasicJsonType::value_t::object:
5884 {
5885 auto seed = combine(type, j.size());
5886 for (const auto& element : j.items())
5887 {
5888 const auto h = std::hash<string_t> {}(element.key());
5889 seed = combine(seed, h);
5890 seed = combine(seed, hash(element.value()));
5891 }
5892 return seed;
5893 }
5894
5895 case BasicJsonType::value_t::array:
5896 {
5897 auto seed = combine(type, j.size());
5898 for (const auto& element : j)
5899 {
5900 seed = combine(seed, hash(element));
5901 }
5902 return seed;
5903 }
5904
5905 case BasicJsonType::value_t::string:
5906 {
5907 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5908 return combine(type, h);
5909 }
5910
5911 case BasicJsonType::value_t::boolean:
5912 {
5913 const auto h = std::hash<bool> {}(j.template get<bool>());
5914 return combine(type, h);
5915 }
5916
5917 case BasicJsonType::value_t::number_integer:
5918 {
5919 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5920 return combine(type, h);
5921 }
5922
5923 case BasicJsonType::value_t::number_unsigned:
5924 {
5925 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5926 return combine(type, h);
5927 }
5928
5929 case BasicJsonType::value_t::number_float:
5930 {
5931 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5932 return combine(type, h);
5933 }
5934
5935 case BasicJsonType::value_t::binary:
5936 {
5937 auto seed = combine(type, j.get_binary().size());
5938 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5939 seed = combine(seed, h);
5940 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5941 for (const auto byte : j.get_binary())
5942 {
5943 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5944 }
5945 return seed;
5946 }
5947
5948 default: // LCOV_EXCL_LINE
5949 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5950 return 0; // LCOV_EXCL_LINE
5951 }
5952}
5953
5954} // namespace detail
5956
5957// #include <nlohmann/detail/input/binary_reader.hpp>
5958// __ _____ _____ _____
5959// __| | __| | | | JSON for Modern C++
5960// | | |__ | | | | | | version 3.11.1
5961// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5962//
5963// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5964// SPDX-License-Identifier: MIT
5965
5966
5967
5968#include <algorithm> // generate_n
5969#include <array> // array
5970#include <cmath> // ldexp
5971#include <cstddef> // size_t
5972#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5973#include <cstdio> // snprintf
5974#include <cstring> // memcpy
5975#include <iterator> // back_inserter
5976#include <limits> // numeric_limits
5977#include <string> // char_traits, string
5978#include <utility> // make_pair, move
5979#include <vector> // vector
5980#include <map> // map
5981
5982// #include <nlohmann/detail/exceptions.hpp>
5983
5984// #include <nlohmann/detail/input/input_adapters.hpp>
5985// __ _____ _____ _____
5986// __| | __| | | | JSON for Modern C++
5987// | | |__ | | | | | | version 3.11.1
5988// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5989//
5990// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5991// SPDX-License-Identifier: MIT
5992
5993
5994
5995#include <array> // array
5996#include <cstddef> // size_t
5997#include <cstring> // strlen
5998#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5999#include <memory> // shared_ptr, make_shared, addressof
6000#include <numeric> // accumulate
6001#include <string> // string, char_traits
6002#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6003#include <utility> // pair, declval
6004
6005#ifndef JSON_NO_IO
6006 #include <cstdio> // FILE *
6007 #include <istream> // istream
6008#endif // JSON_NO_IO
6009
6010// #include <nlohmann/detail/iterators/iterator_traits.hpp>
6011
6012// #include <nlohmann/detail/macro_scope.hpp>
6013
6014
6016namespace detail
6017{
6018
6021
6023// input adapters //
6025
6026#ifndef JSON_NO_IO
6032{
6033 public:
6034 using char_type = char;
6035
6037 explicit file_input_adapter(std::FILE* f) noexcept
6038 : m_file(f)
6039 {
6040 JSON_ASSERT(m_file != nullptr);
6041 }
6042
6043 // make class move-only
6046 file_input_adapter& operator=(const file_input_adapter&) = delete;
6049
6050 std::char_traits<char>::int_type get_character() noexcept
6051 {
6052 return std::fgetc(m_file);
6053 }
6054
6055 private:
6057 std::FILE* m_file;
6058};
6059
6060
6071{
6072 public:
6073 using char_type = char;
6074
6076 {
6077 // clear stream flags; we use underlying streambuf I/O, do not
6078 // maintain ifstream flags, except eof
6079 if (is != nullptr)
6080 {
6081 is->clear(is->rdstate() & std::ios::eofbit);
6082 }
6083 }
6084
6085 explicit input_stream_adapter(std::istream& i)
6086 : is(&i), sb(i.rdbuf())
6087 {}
6088
6089 // delete because of pointer members
6093
6095 : is(rhs.is), sb(rhs.sb)
6096 {
6097 rhs.is = nullptr;
6098 rhs.sb = nullptr;
6099 }
6100
6101 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6102 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6103 // end up as the same value, e.g. 0xFFFFFFFF.
6104 std::char_traits<char>::int_type get_character()
6105 {
6106 auto res = sb->sbumpc();
6107 // set eof manually, as we don't use the istream interface.
6108 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6109 {
6110 is->clear(is->rdstate() | std::ios::eofbit);
6111 }
6112 return res;
6113 }
6114
6115 private:
6117 std::istream* is = nullptr;
6118 std::streambuf* sb = nullptr;
6119};
6120#endif // JSON_NO_IO
6121
6122// General-purpose iterator-based adapter. It might not be as fast as
6123// theoretically possible for some containers, but it is extremely versatile.
6124template<typename IteratorType>
6126{
6127 public:
6128 using char_type = typename std::iterator_traits<IteratorType>::value_type;
6129
6130 iterator_input_adapter(IteratorType first, IteratorType last)
6131 : current(std::move(first)), end(std::move(last))
6132 {}
6133
6134 typename std::char_traits<char_type>::int_type get_character()
6135 {
6137 {
6138 auto result = std::char_traits<char_type>::to_int_type(*current);
6139 std::advance(current, 1);
6140 return result;
6141 }
6142
6143 return std::char_traits<char_type>::eof();
6144 }
6145
6146 private:
6147 IteratorType current;
6148 IteratorType end;
6149
6150 template<typename BaseInputAdapter, size_t T>
6152
6153 bool empty() const
6154 {
6155 return current == end;
6156 }
6157};
6158
6159
6160template<typename BaseInputAdapter, size_t T>
6162
6163template<typename BaseInputAdapter>
6164struct wide_string_input_helper<BaseInputAdapter, 4>
6165{
6166 // UTF-32
6167 static void fill_buffer(BaseInputAdapter& input,
6168 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6169 size_t& utf8_bytes_index,
6170 size_t& utf8_bytes_filled)
6171 {
6172 utf8_bytes_index = 0;
6173
6174 if (JSON_HEDLEY_UNLIKELY(input.empty()))
6175 {
6176 utf8_bytes[0] = std::char_traits<char>::eof();
6177 utf8_bytes_filled = 1;
6178 }
6179 else
6180 {
6181 // get the current character
6182 const auto wc = input.get_character();
6183
6184 // UTF-32 to UTF-8 encoding
6185 if (wc < 0x80)
6186 {
6187 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6188 utf8_bytes_filled = 1;
6189 }
6190 else if (wc <= 0x7FF)
6191 {
6192 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6193 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6194 utf8_bytes_filled = 2;
6195 }
6196 else if (wc <= 0xFFFF)
6197 {
6198 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6199 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6200 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6201 utf8_bytes_filled = 3;
6202 }
6203 else if (wc <= 0x10FFFF)
6204 {
6205 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6206 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6207 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6208 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6209 utf8_bytes_filled = 4;
6210 }
6211 else
6212 {
6213 // unknown character
6214 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6215 utf8_bytes_filled = 1;
6216 }
6217 }
6218 }
6219};
6220
6221template<typename BaseInputAdapter>
6222struct wide_string_input_helper<BaseInputAdapter, 2>
6223{
6224 // UTF-16
6225 static void fill_buffer(BaseInputAdapter& input,
6226 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6227 size_t& utf8_bytes_index,
6228 size_t& utf8_bytes_filled)
6229 {
6230 utf8_bytes_index = 0;
6231
6232 if (JSON_HEDLEY_UNLIKELY(input.empty()))
6233 {
6234 utf8_bytes[0] = std::char_traits<char>::eof();
6235 utf8_bytes_filled = 1;
6236 }
6237 else
6238 {
6239 // get the current character
6240 const auto wc = input.get_character();
6241
6242 // UTF-16 to UTF-8 encoding
6243 if (wc < 0x80)
6244 {
6245 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6246 utf8_bytes_filled = 1;
6247 }
6248 else if (wc <= 0x7FF)
6249 {
6250 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6251 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6252 utf8_bytes_filled = 2;
6253 }
6254 else if (0xD800 > wc || wc >= 0xE000)
6255 {
6256 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6257 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6258 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6259 utf8_bytes_filled = 3;
6260 }
6261 else
6262 {
6263 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6264 {
6265 const auto wc2 = static_cast<unsigned int>(input.get_character());
6266 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6267 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6268 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6269 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6270 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6271 utf8_bytes_filled = 4;
6272 }
6273 else
6274 {
6275 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6276 utf8_bytes_filled = 1;
6277 }
6278 }
6279 }
6280 }
6281};
6282
6283// Wraps another input apdater to convert wide character types into individual bytes.
6284template<typename BaseInputAdapter, typename WideCharType>
6286{
6287 public:
6288 using char_type = char;
6289
6290 wide_string_input_adapter(BaseInputAdapter base)
6291 : base_adapter(base) {}
6292
6293 typename std::char_traits<char>::int_type get_character() noexcept
6294 {
6295 // check if buffer needs to be filled
6297 {
6298 fill_buffer<sizeof(WideCharType)>();
6299
6302 }
6303
6304 // use buffer
6307 return utf8_bytes[utf8_bytes_index++];
6308 }
6309
6310 private:
6311 BaseInputAdapter base_adapter;
6312
6313 template<size_t T>
6315 {
6317 }
6318
6320 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6321
6323 std::size_t utf8_bytes_index = 0;
6325 std::size_t utf8_bytes_filled = 0;
6326};
6327
6328
6329template<typename IteratorType, typename Enable = void>
6331{
6332 using iterator_type = IteratorType;
6333 using char_type = typename std::iterator_traits<iterator_type>::value_type;
6335
6336 static adapter_type create(IteratorType first, IteratorType last)
6337 {
6338 return adapter_type(std::move(first), std::move(last));
6339 }
6340};
6341
6342template<typename T>
6344{
6345 using value_type = typename std::iterator_traits<T>::value_type;
6346 enum
6347 {
6348 value = sizeof(value_type) > 1
6349 };
6350};
6351
6352template<typename IteratorType>
6354{
6355 using iterator_type = IteratorType;
6356 using char_type = typename std::iterator_traits<iterator_type>::value_type;
6359
6360 static adapter_type create(IteratorType first, IteratorType last)
6361 {
6362 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6363 }
6364};
6365
6366// General purpose iterator-based input
6367template<typename IteratorType>
6369{
6371 return factory_type::create(first, last);
6372}
6373
6374// Convenience shorthand from container to iterator
6375// Enables ADL on begin(container) and end(container)
6376// Encloses the using declarations in namespace for not to leak them to outside scope
6377
6378namespace container_input_adapter_factory_impl
6379{
6380
6381using std::begin;
6382using std::end;
6383
6384template<typename ContainerType, typename Enable = void>
6386
6387template<typename ContainerType>
6389 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6390 {
6391 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6392
6393 static adapter_type create(const ContainerType& container)
6394{
6395 return input_adapter(begin(container), end(container));
6396}
6397 };
6398
6399} // namespace container_input_adapter_factory_impl
6400
6401template<typename ContainerType>
6403{
6405}
6406
6407#ifndef JSON_NO_IO
6408// Special cases with fast paths
6409inline file_input_adapter input_adapter(std::FILE* file)
6410{
6411 return file_input_adapter(file);
6412}
6413
6414inline input_stream_adapter input_adapter(std::istream& stream)
6415{
6416 return input_stream_adapter(stream);
6417}
6418
6419inline input_stream_adapter input_adapter(std::istream&& stream)
6420{
6421 return input_stream_adapter(stream);
6422}
6423#endif // JSON_NO_IO
6424
6425using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6426
6427// Null-delimited strings, and the like.
6428template < typename CharT,
6429 typename std::enable_if <
6430 std::is_pointer<CharT>::value&&
6431 !std::is_array<CharT>::value&&
6432 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6433 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6434 int >::type = 0 >
6436{
6437 auto length = std::strlen(reinterpret_cast<const char*>(b));
6438 const auto* ptr = reinterpret_cast<const char*>(b);
6439 return input_adapter(ptr, ptr + length);
6440}
6441
6442template<typename T, std::size_t N>
6443auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6444{
6445 return input_adapter(array, array + N);
6446}
6447
6448// This class only handles inputs of input_buffer_adapter type.
6449// It's required so that expressions like {ptr, len} can be implicitly cast
6450// to the correct adapter.
6452{
6453 public:
6454 template < typename CharT,
6455 typename std::enable_if <
6456 std::is_pointer<CharT>::value&&
6457 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6458 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6459 int >::type = 0 >
6460 span_input_adapter(CharT b, std::size_t l)
6461 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6462
6463 template<class IteratorType,
6464 typename std::enable_if<
6465 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6466 int>::type = 0>
6467 span_input_adapter(IteratorType first, IteratorType last)
6468 : ia(input_adapter(first, last)) {}
6469
6471 {
6472 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6473 }
6474
6475 private:
6477};
6478
6479} // namespace detail
6481
6482// #include <nlohmann/detail/input/json_sax.hpp>
6483// __ _____ _____ _____
6484// __| | __| | | | JSON for Modern C++
6485// | | |__ | | | | | | version 3.11.1
6486// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6487//
6488// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6489// SPDX-License-Identifier: MIT
6490
6491
6492
6493#include <cstddef>
6494#include <string> // string
6495#include <utility> // move
6496#include <vector> // vector
6497
6498// #include <nlohmann/detail/exceptions.hpp>
6499
6500// #include <nlohmann/detail/macro_scope.hpp>
6501
6502// #include <nlohmann/detail/string_concat.hpp>
6503
6504
6506
6515template<typename BasicJsonType>
6517{
6518 using number_integer_t = typename BasicJsonType::number_integer_t;
6519 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6520 using number_float_t = typename BasicJsonType::number_float_t;
6521 using string_t = typename BasicJsonType::string_t;
6522 using binary_t = typename BasicJsonType::binary_t;
6523
6528 virtual bool null() = 0;
6529
6535 virtual bool boolean(bool val) = 0;
6536
6542 virtual bool number_integer(number_integer_t val) = 0;
6543
6549 virtual bool number_unsigned(number_unsigned_t val) = 0;
6550
6557 virtual bool number_float(number_float_t val, const string_t& s) = 0;
6558
6565 virtual bool string(string_t& val) = 0;
6566
6573 virtual bool binary(binary_t& val) = 0;
6574
6581 virtual bool start_object(std::size_t elements) = 0;
6582
6589 virtual bool key(string_t& val) = 0;
6590
6595 virtual bool end_object() = 0;
6596
6603 virtual bool start_array(std::size_t elements) = 0;
6604
6609 virtual bool end_array() = 0;
6610
6618 virtual bool parse_error(std::size_t position,
6619 const std::string& last_token,
6620 const detail::exception& ex) = 0;
6621
6622 json_sax() = default;
6623 json_sax(const json_sax&) = default;
6624 json_sax(json_sax&&) noexcept = default;
6625 json_sax& operator=(const json_sax&) = default;
6626 json_sax& operator=(json_sax&&) noexcept = default;
6627 virtual ~json_sax() = default;
6628};
6629
6630
6631namespace detail
6632{
6646template<typename BasicJsonType>
6648{
6649 public:
6650 using number_integer_t = typename BasicJsonType::number_integer_t;
6651 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6652 using number_float_t = typename BasicJsonType::number_float_t;
6653 using string_t = typename BasicJsonType::string_t;
6654 using binary_t = typename BasicJsonType::binary_t;
6655
6661 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6662 : root(r), allow_exceptions(allow_exceptions_)
6663 {}
6664
6665 // make class move-only
6667 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6669 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6671
6672 bool null()
6673 {
6674 handle_value(nullptr);
6675 return true;
6676 }
6677
6678 bool boolean(bool val)
6679 {
6680 handle_value(val);
6681 return true;
6682 }
6683
6685 {
6686 handle_value(val);
6687 return true;
6688 }
6689
6691 {
6692 handle_value(val);
6693 return true;
6694 }
6695
6696 bool number_float(number_float_t val, const string_t& /*unused*/)
6697 {
6698 handle_value(val);
6699 return true;
6700 }
6701
6702 bool string(string_t& val)
6703 {
6704 handle_value(val);
6705 return true;
6706 }
6707
6708 bool binary(binary_t& val)
6709 {
6710 handle_value(std::move(val));
6711 return true;
6712 }
6713
6714 bool start_object(std::size_t len)
6715 {
6716 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6717
6718 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6719 {
6720 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6721 }
6722
6723 return true;
6724 }
6725
6726 bool key(string_t& val)
6727 {
6728 JSON_ASSERT(!ref_stack.empty());
6729 JSON_ASSERT(ref_stack.back()->is_object());
6730
6731 // add null at given key and store the reference for later
6732 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6733 return true;
6734 }
6735
6737 {
6738 JSON_ASSERT(!ref_stack.empty());
6739 JSON_ASSERT(ref_stack.back()->is_object());
6740
6741 ref_stack.back()->set_parents();
6742 ref_stack.pop_back();
6743 return true;
6744 }
6745
6746 bool start_array(std::size_t len)
6747 {
6748 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6749
6750 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6751 {
6752 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6753 }
6754
6755 return true;
6756 }
6757
6759 {
6760 JSON_ASSERT(!ref_stack.empty());
6761 JSON_ASSERT(ref_stack.back()->is_array());
6762
6763 ref_stack.back()->set_parents();
6764 ref_stack.pop_back();
6765 return true;
6766 }
6767
6768 template<class Exception>
6769 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6770 const Exception& ex)
6771 {
6772 errored = true;
6773 static_cast<void>(ex);
6774 if (allow_exceptions)
6775 {
6776 JSON_THROW(ex);
6777 }
6778 return false;
6779 }
6780
6781 constexpr bool is_errored() const
6782 {
6783 return errored;
6784 }
6785
6786 private:
6793 template<typename Value>
6795 BasicJsonType* handle_value(Value&& v)
6796 {
6797 if (ref_stack.empty())
6798 {
6799 root = BasicJsonType(std::forward<Value>(v));
6800 return &root;
6801 }
6802
6803 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6804
6805 if (ref_stack.back()->is_array())
6806 {
6807 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6808 return &(ref_stack.back()->m_value.array->back());
6809 }
6810
6811 JSON_ASSERT(ref_stack.back()->is_object());
6812 JSON_ASSERT(object_element);
6813 *object_element = BasicJsonType(std::forward<Value>(v));
6814 return object_element;
6815 }
6816
6818 BasicJsonType& root;
6820 std::vector<BasicJsonType*> ref_stack {};
6822 BasicJsonType* object_element = nullptr;
6824 bool errored = false;
6826 const bool allow_exceptions = true;
6827};
6828
6829template<typename BasicJsonType>
6831{
6832 public:
6833 using number_integer_t = typename BasicJsonType::number_integer_t;
6834 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6835 using number_float_t = typename BasicJsonType::number_float_t;
6836 using string_t = typename BasicJsonType::string_t;
6837 using binary_t = typename BasicJsonType::binary_t;
6840
6842 const parser_callback_t cb,
6843 const bool allow_exceptions_ = true)
6844 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6845 {
6846 keep_stack.push_back(true);
6847 }
6848
6849 // make class move-only
6851 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6853 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6855
6856 bool null()
6857 {
6858 handle_value(nullptr);
6859 return true;
6860 }
6861
6862 bool boolean(bool val)
6863 {
6864 handle_value(val);
6865 return true;
6866 }
6867
6869 {
6870 handle_value(val);
6871 return true;
6872 }
6873
6875 {
6876 handle_value(val);
6877 return true;
6878 }
6879
6880 bool number_float(number_float_t val, const string_t& /*unused*/)
6881 {
6882 handle_value(val);
6883 return true;
6884 }
6885
6886 bool string(string_t& val)
6887 {
6888 handle_value(val);
6889 return true;
6890 }
6891
6892 bool binary(binary_t& val)
6893 {
6894 handle_value(std::move(val));
6895 return true;
6896 }
6897
6898 bool start_object(std::size_t len)
6899 {
6900 // check callback for object start
6901 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6902 keep_stack.push_back(keep);
6903
6904 auto val = handle_value(BasicJsonType::value_t::object, true);
6905 ref_stack.push_back(val.second);
6906
6907 // check object limit
6908 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6909 {
6910 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6911 }
6912
6913 return true;
6914 }
6915
6916 bool key(string_t& val)
6917 {
6918 BasicJsonType k = BasicJsonType(val);
6919
6920 // check callback for key
6921 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6922 key_keep_stack.push_back(keep);
6923
6924 // add discarded value at given key and store the reference for later
6925 if (keep && ref_stack.back())
6926 {
6927 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6928 }
6929
6930 return true;
6931 }
6932
6934 {
6935 if (ref_stack.back())
6936 {
6937 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6938 {
6939 // discard object
6940 *ref_stack.back() = discarded;
6941 }
6942 else
6943 {
6944 ref_stack.back()->set_parents();
6945 }
6946 }
6947
6948 JSON_ASSERT(!ref_stack.empty());
6949 JSON_ASSERT(!keep_stack.empty());
6950 ref_stack.pop_back();
6951 keep_stack.pop_back();
6952
6953 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6954 {
6955 // remove discarded value
6956 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6957 {
6958 if (it->is_discarded())
6959 {
6960 ref_stack.back()->erase(it);
6961 break;
6962 }
6963 }
6964 }
6965
6966 return true;
6967 }
6968
6969 bool start_array(std::size_t len)
6970 {
6971 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6972 keep_stack.push_back(keep);
6973
6974 auto val = handle_value(BasicJsonType::value_t::array, true);
6975 ref_stack.push_back(val.second);
6976
6977 // check array limit
6978 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6979 {
6980 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6981 }
6982
6983 return true;
6984 }
6985
6987 {
6988 bool keep = true;
6989
6990 if (ref_stack.back())
6991 {
6992 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6993 if (keep)
6994 {
6995 ref_stack.back()->set_parents();
6996 }
6997 else
6998 {
6999 // discard array
7000 *ref_stack.back() = discarded;
7001 }
7002 }
7003
7004 JSON_ASSERT(!ref_stack.empty());
7005 JSON_ASSERT(!keep_stack.empty());
7006 ref_stack.pop_back();
7007 keep_stack.pop_back();
7008
7009 // remove discarded value
7010 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
7011 {
7012 ref_stack.back()->m_value.array->pop_back();
7013 }
7014
7015 return true;
7016 }
7017
7018 template<class Exception>
7019 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
7020 const Exception& ex)
7021 {
7022 errored = true;
7023 static_cast<void>(ex);
7024 if (allow_exceptions)
7025 {
7026 JSON_THROW(ex);
7027 }
7028 return false;
7029 }
7030
7031 constexpr bool is_errored() const
7032 {
7033 return errored;
7034 }
7035
7036 private:
7052 template<typename Value>
7053 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
7054 {
7055 JSON_ASSERT(!keep_stack.empty());
7056
7057 // do not handle this value if we know it would be added to a discarded
7058 // container
7059 if (!keep_stack.back())
7060 {
7061 return {false, nullptr};
7062 }
7063
7064 // create value
7065 auto value = BasicJsonType(std::forward<Value>(v));
7066
7067 // check callback
7068 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
7069
7070 // do not handle this value if we just learnt it shall be discarded
7071 if (!keep)
7072 {
7073 return {false, nullptr};
7074 }
7075
7076 if (ref_stack.empty())
7077 {
7078 root = std::move(value);
7079 return {true, &root};
7080 }
7081
7082 // skip this value if we already decided to skip the parent
7083 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
7084 if (!ref_stack.back())
7085 {
7086 return {false, nullptr};
7087 }
7088
7089 // we now only expect arrays and objects
7090 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
7091
7092 // array
7093 if (ref_stack.back()->is_array())
7094 {
7095 ref_stack.back()->m_value.array->emplace_back(std::move(value));
7096 return {true, &(ref_stack.back()->m_value.array->back())};
7097 }
7098
7099 // object
7100 JSON_ASSERT(ref_stack.back()->is_object());
7101 // check if we should store an element for the current key
7102 JSON_ASSERT(!key_keep_stack.empty());
7103 const bool store_element = key_keep_stack.back();
7104 key_keep_stack.pop_back();
7105
7106 if (!store_element)
7107 {
7108 return {false, nullptr};
7109 }
7110
7111 JSON_ASSERT(object_element);
7112 *object_element = std::move(value);
7113 return {true, object_element};
7114 }
7115
7117 BasicJsonType& root;
7119 std::vector<BasicJsonType*> ref_stack {};
7121 std::vector<bool> keep_stack {};
7123 std::vector<bool> key_keep_stack {};
7125 BasicJsonType* object_element = nullptr;
7127 bool errored = false;
7129 const parser_callback_t callback = nullptr;
7131 const bool allow_exceptions = true;
7133 BasicJsonType discarded = BasicJsonType::value_t::discarded;
7134};
7135
7136template<typename BasicJsonType>
7138{
7139 public:
7140 using number_integer_t = typename BasicJsonType::number_integer_t;
7141 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7142 using number_float_t = typename BasicJsonType::number_float_t;
7143 using string_t = typename BasicJsonType::string_t;
7144 using binary_t = typename BasicJsonType::binary_t;
7145
7146 bool null()
7147 {
7148 return true;
7149 }
7150
7151 bool boolean(bool /*unused*/)
7152 {
7153 return true;
7154 }
7155
7157 {
7158 return true;
7159 }
7160
7162 {
7163 return true;
7164 }
7165
7166 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
7167 {
7168 return true;
7169 }
7170
7171 bool string(string_t& /*unused*/)
7172 {
7173 return true;
7174 }
7175
7176 bool binary(binary_t& /*unused*/)
7177 {
7178 return true;
7179 }
7180
7181 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7182 {
7183 return true;
7184 }
7185
7186 bool key(string_t& /*unused*/)
7187 {
7188 return true;
7189 }
7190
7192 {
7193 return true;
7194 }
7195
7196 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7197 {
7198 return true;
7199 }
7200
7202 {
7203 return true;
7204 }
7205
7206 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
7207 {
7208 return false;
7209 }
7210};
7211
7212} // namespace detail
7214
7215// #include <nlohmann/detail/input/lexer.hpp>
7216// __ _____ _____ _____
7217// __| | __| | | | JSON for Modern C++
7218// | | |__ | | | | | | version 3.11.1
7219// |_____|_____|_____|_|___| https://github.com/nlohmann/json
7220//
7221// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7222// SPDX-License-Identifier: MIT
7223
7224
7225
7226#include <array> // array
7227#include <clocale> // localeconv
7228#include <cstddef> // size_t
7229#include <cstdio> // snprintf
7230#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7231#include <initializer_list> // initializer_list
7232#include <string> // char_traits, string
7233#include <utility> // move
7234#include <vector> // vector
7235
7236// #include <nlohmann/detail/input/input_adapters.hpp>
7237
7238// #include <nlohmann/detail/input/position_t.hpp>
7239
7240// #include <nlohmann/detail/macro_scope.hpp>
7241
7242
7244namespace detail
7245{
7246
7248// lexer //
7250
7251template<typename BasicJsonType>
7253{
7254 public:
7256 enum class token_type
7257 {
7258 uninitialized,
7259 literal_true,
7260 literal_false,
7261 literal_null,
7262 value_string,
7263 value_unsigned,
7264 value_integer,
7265 value_float,
7266 begin_array,
7267 begin_object,
7268 end_array,
7269 end_object,
7270 name_separator,
7271 value_separator,
7272 parse_error,
7273 end_of_input,
7274 literal_or_value
7275 };
7276
7280 static const char* token_type_name(const token_type t) noexcept
7281 {
7282 switch (t)
7283 {
7284 case token_type::uninitialized:
7285 return "<uninitialized>";
7286 case token_type::literal_true:
7287 return "true literal";
7288 case token_type::literal_false:
7289 return "false literal";
7290 case token_type::literal_null:
7291 return "null literal";
7292 case token_type::value_string:
7293 return "string literal";
7294 case token_type::value_unsigned:
7295 case token_type::value_integer:
7296 case token_type::value_float:
7297 return "number literal";
7298 case token_type::begin_array:
7299 return "'['";
7300 case token_type::begin_object:
7301 return "'{'";
7302 case token_type::end_array:
7303 return "']'";
7304 case token_type::end_object:
7305 return "'}'";
7306 case token_type::name_separator:
7307 return "':'";
7308 case token_type::value_separator:
7309 return "','";
7310 case token_type::parse_error:
7311 return "<parse error>";
7312 case token_type::end_of_input:
7313 return "end of input";
7314 case token_type::literal_or_value:
7315 return "'[', '{', or a literal";
7316 // LCOV_EXCL_START
7317 default: // catch non-enum values
7318 return "unknown token";
7319 // LCOV_EXCL_STOP
7320 }
7321 }
7322};
7328template<typename BasicJsonType, typename InputAdapterType>
7329class lexer : public lexer_base<BasicJsonType>
7330{
7331 using number_integer_t = typename BasicJsonType::number_integer_t;
7332 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7333 using number_float_t = typename BasicJsonType::number_float_t;
7334 using string_t = typename BasicJsonType::string_t;
7335 using char_type = typename InputAdapterType::char_type;
7336 using char_int_type = typename std::char_traits<char_type>::int_type;
7337
7338 public:
7340
7341 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7342 : ia(std::move(adapter))
7343 , ignore_comments(ignore_comments_)
7344 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7345 {}
7346
7347 // delete because of pointer members
7348 lexer(const lexer&) = delete;
7349 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7350 lexer& operator=(lexer&) = delete;
7351 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7352 ~lexer() = default;
7353
7354 private:
7356 // locales
7358
7361 static char get_decimal_point() noexcept
7362 {
7363 const auto* loc = localeconv();
7364 JSON_ASSERT(loc != nullptr);
7365 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7366 }
7367
7369 // scan functions
7371
7388 {
7389 // this function only makes sense after reading `\u`
7390 JSON_ASSERT(current == 'u');
7391 int codepoint = 0;
7392
7393 const auto factors = { 12u, 8u, 4u, 0u };
7394 for (const auto factor : factors)
7395 {
7396 get();
7397
7398 if (current >= '0' && current <= '9')
7399 {
7400 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7401 }
7402 else if (current >= 'A' && current <= 'F')
7403 {
7404 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7405 }
7406 else if (current >= 'a' && current <= 'f')
7407 {
7408 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7409 }
7410 else
7411 {
7412 return -1;
7413 }
7414 }
7415
7416 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7417 return codepoint;
7418 }
7419
7435 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7436 {
7437 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7438 add(current);
7439
7440 for (auto range = ranges.begin(); range != ranges.end(); ++range)
7441 {
7442 get();
7443 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
7444 {
7445 add(current);
7446 }
7447 else
7448 {
7449 error_message = "invalid string: ill-formed UTF-8 byte";
7450 return false;
7451 }
7452 }
7453
7454 return true;
7455 }
7456
7473 {
7474 // reset token_buffer (ignore opening quote)
7475 reset();
7476
7477 // we entered the function by reading an open quote
7478 JSON_ASSERT(current == '\"');
7479
7480 while (true)
7481 {
7482 // get next character
7483 switch (get())
7484 {
7485 // end of file while parsing string
7486 case std::char_traits<char_type>::eof():
7487 {
7488 error_message = "invalid string: missing closing quote";
7489 return token_type::parse_error;
7490 }
7491
7492 // closing quote
7493 case '\"':
7494 {
7495 return token_type::value_string;
7496 }
7497
7498 // escapes
7499 case '\\':
7500 {
7501 switch (get())
7502 {
7503 // quotation mark
7504 case '\"':
7505 add('\"');
7506 break;
7507 // reverse solidus
7508 case '\\':
7509 add('\\');
7510 break;
7511 // solidus
7512 case '/':
7513 add('/');
7514 break;
7515 // backspace
7516 case 'b':
7517 add('\b');
7518 break;
7519 // form feed
7520 case 'f':
7521 add('\f');
7522 break;
7523 // line feed
7524 case 'n':
7525 add('\n');
7526 break;
7527 // carriage return
7528 case 'r':
7529 add('\r');
7530 break;
7531 // tab
7532 case 't':
7533 add('\t');
7534 break;
7535
7536 // unicode escapes
7537 case 'u':
7538 {
7539 const int codepoint1 = get_codepoint();
7540 int codepoint = codepoint1; // start with codepoint1
7541
7542 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7543 {
7544 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7545 return token_type::parse_error;
7546 }
7547
7548 // check if code point is a high surrogate
7549 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7550 {
7551 // expect next \uxxxx entry
7552 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7553 {
7554 const int codepoint2 = get_codepoint();
7555
7556 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7557 {
7558 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7559 return token_type::parse_error;
7560 }
7561
7562 // check if codepoint2 is a low surrogate
7563 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7564 {
7565 // overwrite codepoint
7566 codepoint = static_cast<int>(
7567 // high surrogate occupies the most significant 22 bits
7568 (static_cast<unsigned int>(codepoint1) << 10u)
7569 // low surrogate occupies the least significant 15 bits
7570 + static_cast<unsigned int>(codepoint2)
7571 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7572 // in the result, so we have to subtract with:
7573 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7574 - 0x35FDC00u);
7575 }
7576 else
7577 {
7578 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7579 return token_type::parse_error;
7580 }
7581 }
7582 else
7583 {
7584 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7585 return token_type::parse_error;
7586 }
7587 }
7588 else
7589 {
7590 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7591 {
7592 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7593 return token_type::parse_error;
7594 }
7595 }
7596
7597 // result of the above calculation yields a proper codepoint
7598 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7599
7600 // translate codepoint into bytes
7601 if (codepoint < 0x80)
7602 {
7603 // 1-byte characters: 0xxxxxxx (ASCII)
7604 add(static_cast<char_int_type>(codepoint));
7605 }
7606 else if (codepoint <= 0x7FF)
7607 {
7608 // 2-byte characters: 110xxxxx 10xxxxxx
7609 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7610 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7611 }
7612 else if (codepoint <= 0xFFFF)
7613 {
7614 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7615 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7616 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7617 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7618 }
7619 else
7620 {
7621 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7622 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7623 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7624 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7625 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7626 }
7627
7628 break;
7629 }
7630
7631 // other characters after escape
7632 default:
7633 error_message = "invalid string: forbidden character after backslash";
7634 return token_type::parse_error;
7635 }
7636
7637 break;
7638 }
7639
7640 // invalid control characters
7641 case 0x00:
7642 {
7643 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7644 return token_type::parse_error;
7645 }
7646
7647 case 0x01:
7648 {
7649 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7650 return token_type::parse_error;
7651 }
7652
7653 case 0x02:
7654 {
7655 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7656 return token_type::parse_error;
7657 }
7658
7659 case 0x03:
7660 {
7661 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7662 return token_type::parse_error;
7663 }
7664
7665 case 0x04:
7666 {
7667 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7668 return token_type::parse_error;
7669 }
7670
7671 case 0x05:
7672 {
7673 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7674 return token_type::parse_error;
7675 }
7676
7677 case 0x06:
7678 {
7679 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7680 return token_type::parse_error;
7681 }
7682
7683 case 0x07:
7684 {
7685 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7686 return token_type::parse_error;
7687 }
7688
7689 case 0x08:
7690 {
7691 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7692 return token_type::parse_error;
7693 }
7694
7695 case 0x09:
7696 {
7697 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7698 return token_type::parse_error;
7699 }
7700
7701 case 0x0A:
7702 {
7703 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7704 return token_type::parse_error;
7705 }
7706
7707 case 0x0B:
7708 {
7709 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7710 return token_type::parse_error;
7711 }
7712
7713 case 0x0C:
7714 {
7715 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7716 return token_type::parse_error;
7717 }
7718
7719 case 0x0D:
7720 {
7721 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7722 return token_type::parse_error;
7723 }
7724
7725 case 0x0E:
7726 {
7727 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7728 return token_type::parse_error;
7729 }
7730
7731 case 0x0F:
7732 {
7733 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7734 return token_type::parse_error;
7735 }
7736
7737 case 0x10:
7738 {
7739 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7740 return token_type::parse_error;
7741 }
7742
7743 case 0x11:
7744 {
7745 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7746 return token_type::parse_error;
7747 }
7748
7749 case 0x12:
7750 {
7751 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7752 return token_type::parse_error;
7753 }
7754
7755 case 0x13:
7756 {
7757 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7758 return token_type::parse_error;
7759 }
7760
7761 case 0x14:
7762 {
7763 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7764 return token_type::parse_error;
7765 }
7766
7767 case 0x15:
7768 {
7769 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7770 return token_type::parse_error;
7771 }
7772
7773 case 0x16:
7774 {
7775 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7776 return token_type::parse_error;
7777 }
7778
7779 case 0x17:
7780 {
7781 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7782 return token_type::parse_error;
7783 }
7784
7785 case 0x18:
7786 {
7787 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7788 return token_type::parse_error;
7789 }
7790
7791 case 0x19:
7792 {
7793 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7794 return token_type::parse_error;
7795 }
7796
7797 case 0x1A:
7798 {
7799 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7800 return token_type::parse_error;
7801 }
7802
7803 case 0x1B:
7804 {
7805 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7806 return token_type::parse_error;
7807 }
7808
7809 case 0x1C:
7810 {
7811 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7812 return token_type::parse_error;
7813 }
7814
7815 case 0x1D:
7816 {
7817 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7818 return token_type::parse_error;
7819 }
7820
7821 case 0x1E:
7822 {
7823 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7824 return token_type::parse_error;
7825 }
7826
7827 case 0x1F:
7828 {
7829 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7830 return token_type::parse_error;
7831 }
7832
7833 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7834 case 0x20:
7835 case 0x21:
7836 case 0x23:
7837 case 0x24:
7838 case 0x25:
7839 case 0x26:
7840 case 0x27:
7841 case 0x28:
7842 case 0x29:
7843 case 0x2A:
7844 case 0x2B:
7845 case 0x2C:
7846 case 0x2D:
7847 case 0x2E:
7848 case 0x2F:
7849 case 0x30:
7850 case 0x31:
7851 case 0x32:
7852 case 0x33:
7853 case 0x34:
7854 case 0x35:
7855 case 0x36:
7856 case 0x37:
7857 case 0x38:
7858 case 0x39:
7859 case 0x3A:
7860 case 0x3B:
7861 case 0x3C:
7862 case 0x3D:
7863 case 0x3E:
7864 case 0x3F:
7865 case 0x40:
7866 case 0x41:
7867 case 0x42:
7868 case 0x43:
7869 case 0x44:
7870 case 0x45:
7871 case 0x46:
7872 case 0x47:
7873 case 0x48:
7874 case 0x49:
7875 case 0x4A:
7876 case 0x4B:
7877 case 0x4C:
7878 case 0x4D:
7879 case 0x4E:
7880 case 0x4F:
7881 case 0x50:
7882 case 0x51:
7883 case 0x52:
7884 case 0x53:
7885 case 0x54:
7886 case 0x55:
7887 case 0x56:
7888 case 0x57:
7889 case 0x58:
7890 case 0x59:
7891 case 0x5A:
7892 case 0x5B:
7893 case 0x5D:
7894 case 0x5E:
7895 case 0x5F:
7896 case 0x60:
7897 case 0x61:
7898 case 0x62:
7899 case 0x63:
7900 case 0x64:
7901 case 0x65:
7902 case 0x66:
7903 case 0x67:
7904 case 0x68:
7905 case 0x69:
7906 case 0x6A:
7907 case 0x6B:
7908 case 0x6C:
7909 case 0x6D:
7910 case 0x6E:
7911 case 0x6F:
7912 case 0x70:
7913 case 0x71:
7914 case 0x72:
7915 case 0x73:
7916 case 0x74:
7917 case 0x75:
7918 case 0x76:
7919 case 0x77:
7920 case 0x78:
7921 case 0x79:
7922 case 0x7A:
7923 case 0x7B:
7924 case 0x7C:
7925 case 0x7D:
7926 case 0x7E:
7927 case 0x7F:
7928 {
7929 add(current);
7930 break;
7931 }
7932
7933 // U+0080..U+07FF: bytes C2..DF 80..BF
7934 case 0xC2:
7935 case 0xC3:
7936 case 0xC4:
7937 case 0xC5:
7938 case 0xC6:
7939 case 0xC7:
7940 case 0xC8:
7941 case 0xC9:
7942 case 0xCA:
7943 case 0xCB:
7944 case 0xCC:
7945 case 0xCD:
7946 case 0xCE:
7947 case 0xCF:
7948 case 0xD0:
7949 case 0xD1:
7950 case 0xD2:
7951 case 0xD3:
7952 case 0xD4:
7953 case 0xD5:
7954 case 0xD6:
7955 case 0xD7:
7956 case 0xD8:
7957 case 0xD9:
7958 case 0xDA:
7959 case 0xDB:
7960 case 0xDC:
7961 case 0xDD:
7962 case 0xDE:
7963 case 0xDF:
7964 {
7965 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7966 {
7967 return token_type::parse_error;
7968 }
7969 break;
7970 }
7971
7972 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7973 case 0xE0:
7974 {
7975 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7976 {
7977 return token_type::parse_error;
7978 }
7979 break;
7980 }
7981
7982 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7983 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7984 case 0xE1:
7985 case 0xE2:
7986 case 0xE3:
7987 case 0xE4:
7988 case 0xE5:
7989 case 0xE6:
7990 case 0xE7:
7991 case 0xE8:
7992 case 0xE9:
7993 case 0xEA:
7994 case 0xEB:
7995 case 0xEC:
7996 case 0xEE:
7997 case 0xEF:
7998 {
7999 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8000 {
8001 return token_type::parse_error;
8002 }
8003 break;
8004 }
8005
8006 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8007 case 0xED:
8008 {
8009 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8010 {
8011 return token_type::parse_error;
8012 }
8013 break;
8014 }
8015
8016 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8017 case 0xF0:
8018 {
8019 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8020 {
8021 return token_type::parse_error;
8022 }
8023 break;
8024 }
8025
8026 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8027 case 0xF1:
8028 case 0xF2:
8029 case 0xF3:
8030 {
8031 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8032 {
8033 return token_type::parse_error;
8034 }
8035 break;
8036 }
8037
8038 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8039 case 0xF4:
8040 {
8041 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8042 {
8043 return token_type::parse_error;
8044 }
8045 break;
8046 }
8047
8048 // remaining bytes (80..C1 and F5..FF) are ill-formed
8049 default:
8050 {
8051 error_message = "invalid string: ill-formed UTF-8 byte";
8052 return token_type::parse_error;
8053 }
8054 }
8055 }
8056 }
8057
8063 {
8064 switch (get())
8065 {
8066 // single-line comments skip input until a newline or EOF is read
8067 case '/':
8068 {
8069 while (true)
8070 {
8071 switch (get())
8072 {
8073 case '\n':
8074 case '\r':
8075 case std::char_traits<char_type>::eof():
8076 case '\0':
8077 return true;
8078
8079 default:
8080 break;
8081 }
8082 }
8083 }
8084
8085 // multi-line comments skip input until */ is read
8086 case '*':
8087 {
8088 while (true)
8089 {
8090 switch (get())
8091 {
8092 case std::char_traits<char_type>::eof():
8093 case '\0':
8094 {
8095 error_message = "invalid comment; missing closing '*/'";
8096 return false;
8097 }
8098
8099 case '*':
8100 {
8101 switch (get())
8102 {
8103 case '/':
8104 return true;
8105
8106 default:
8107 {
8108 unget();
8109 continue;
8110 }
8111 }
8112 }
8113
8114 default:
8115 continue;
8116 }
8117 }
8118 }
8119
8120 // unexpected character after reading '/'
8121 default:
8122 {
8123 error_message = "invalid comment; expecting '/' or '*' after '/'";
8124 return false;
8125 }
8126 }
8127 }
8128
8130 static void strtof(float& f, const char* str, char** endptr) noexcept
8131 {
8132 f = std::strtof(str, endptr);
8133 }
8134
8136 static void strtof(double& f, const char* str, char** endptr) noexcept
8137 {
8138 f = std::strtod(str, endptr);
8139 }
8140
8142 static void strtof(long double& f, const char* str, char** endptr) noexcept
8143 {
8144 f = std::strtold(str, endptr);
8145 }
8146
8187 token_type scan_number() // lgtm [cpp/use-of-goto]
8188 {
8189 // reset token_buffer to store the number's bytes
8190 reset();
8191
8192 // the type of the parsed number; initially set to unsigned; will be
8193 // changed if minus sign, decimal point or exponent is read
8194 token_type number_type = token_type::value_unsigned;
8195
8196 // state (init): we just found out we need to scan a number
8197 switch (current)
8198 {
8199 case '-':
8200 {
8201 add(current);
8202 goto scan_number_minus;
8203 }
8204
8205 case '0':
8206 {
8207 add(current);
8208 goto scan_number_zero;
8209 }
8210
8211 case '1':
8212 case '2':
8213 case '3':
8214 case '4':
8215 case '5':
8216 case '6':
8217 case '7':
8218 case '8':
8219 case '9':
8220 {
8221 add(current);
8222 goto scan_number_any1;
8223 }
8224
8225 // all other characters are rejected outside scan_number()
8226 default: // LCOV_EXCL_LINE
8227 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8228 }
8229
8230scan_number_minus:
8231 // state: we just parsed a leading minus sign
8232 number_type = token_type::value_integer;
8233 switch (get())
8234 {
8235 case '0':
8236 {
8237 add(current);
8238 goto scan_number_zero;
8239 }
8240
8241 case '1':
8242 case '2':
8243 case '3':
8244 case '4':
8245 case '5':
8246 case '6':
8247 case '7':
8248 case '8':
8249 case '9':
8250 {
8251 add(current);
8252 goto scan_number_any1;
8253 }
8254
8255 default:
8256 {
8257 error_message = "invalid number; expected digit after '-'";
8258 return token_type::parse_error;
8259 }
8260 }
8261
8262scan_number_zero:
8263 // state: we just parse a zero (maybe with a leading minus sign)
8264 switch (get())
8265 {
8266 case '.':
8267 {
8268 add(decimal_point_char);
8269 goto scan_number_decimal1;
8270 }
8271
8272 case 'e':
8273 case 'E':
8274 {
8275 add(current);
8276 goto scan_number_exponent;
8277 }
8278
8279 default:
8280 goto scan_number_done;
8281 }
8282
8283scan_number_any1:
8284 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8285 switch (get())
8286 {
8287 case '0':
8288 case '1':
8289 case '2':
8290 case '3':
8291 case '4':
8292 case '5':
8293 case '6':
8294 case '7':
8295 case '8':
8296 case '9':
8297 {
8298 add(current);
8299 goto scan_number_any1;
8300 }
8301
8302 case '.':
8303 {
8304 add(decimal_point_char);
8305 goto scan_number_decimal1;
8306 }
8307
8308 case 'e':
8309 case 'E':
8310 {
8311 add(current);
8312 goto scan_number_exponent;
8313 }
8314
8315 default:
8316 goto scan_number_done;
8317 }
8318
8319scan_number_decimal1:
8320 // state: we just parsed a decimal point
8321 number_type = token_type::value_float;
8322 switch (get())
8323 {
8324 case '0':
8325 case '1':
8326 case '2':
8327 case '3':
8328 case '4':
8329 case '5':
8330 case '6':
8331 case '7':
8332 case '8':
8333 case '9':
8334 {
8335 add(current);
8336 goto scan_number_decimal2;
8337 }
8338
8339 default:
8340 {
8341 error_message = "invalid number; expected digit after '.'";
8342 return token_type::parse_error;
8343 }
8344 }
8345
8346scan_number_decimal2:
8347 // we just parsed at least one number after a decimal point
8348 switch (get())
8349 {
8350 case '0':
8351 case '1':
8352 case '2':
8353 case '3':
8354 case '4':
8355 case '5':
8356 case '6':
8357 case '7':
8358 case '8':
8359 case '9':
8360 {
8361 add(current);
8362 goto scan_number_decimal2;
8363 }
8364
8365 case 'e':
8366 case 'E':
8367 {
8368 add(current);
8369 goto scan_number_exponent;
8370 }
8371
8372 default:
8373 goto scan_number_done;
8374 }
8375
8376scan_number_exponent:
8377 // we just parsed an exponent
8378 number_type = token_type::value_float;
8379 switch (get())
8380 {
8381 case '+':
8382 case '-':
8383 {
8384 add(current);
8385 goto scan_number_sign;
8386 }
8387
8388 case '0':
8389 case '1':
8390 case '2':
8391 case '3':
8392 case '4':
8393 case '5':
8394 case '6':
8395 case '7':
8396 case '8':
8397 case '9':
8398 {
8399 add(current);
8400 goto scan_number_any2;
8401 }
8402
8403 default:
8404 {
8405 error_message =
8406 "invalid number; expected '+', '-', or digit after exponent";
8407 return token_type::parse_error;
8408 }
8409 }
8410
8411scan_number_sign:
8412 // we just parsed an exponent sign
8413 switch (get())
8414 {
8415 case '0':
8416 case '1':
8417 case '2':
8418 case '3':
8419 case '4':
8420 case '5':
8421 case '6':
8422 case '7':
8423 case '8':
8424 case '9':
8425 {
8426 add(current);
8427 goto scan_number_any2;
8428 }
8429
8430 default:
8431 {
8432 error_message = "invalid number; expected digit after exponent sign";
8433 return token_type::parse_error;
8434 }
8435 }
8436
8437scan_number_any2:
8438 // we just parsed a number after the exponent or exponent sign
8439 switch (get())
8440 {
8441 case '0':
8442 case '1':
8443 case '2':
8444 case '3':
8445 case '4':
8446 case '5':
8447 case '6':
8448 case '7':
8449 case '8':
8450 case '9':
8451 {
8452 add(current);
8453 goto scan_number_any2;
8454 }
8455
8456 default:
8457 goto scan_number_done;
8458 }
8459
8460scan_number_done:
8461 // unget the character after the number (we only read it to know that
8462 // we are done scanning a number)
8463 unget();
8464
8465 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8466 errno = 0;
8467
8468 // try to parse integers first and fall back to floats
8469 if (number_type == token_type::value_unsigned)
8470 {
8471 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8472
8473 // we checked the number format before
8474 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8475
8476 if (errno == 0)
8477 {
8478 value_unsigned = static_cast<number_unsigned_t>(x);
8479 if (value_unsigned == x)
8480 {
8481 return token_type::value_unsigned;
8482 }
8483 }
8484 }
8485 else if (number_type == token_type::value_integer)
8486 {
8487 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8488
8489 // we checked the number format before
8490 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8491
8492 if (errno == 0)
8493 {
8494 value_integer = static_cast<number_integer_t>(x);
8495 if (value_integer == x)
8496 {
8497 return token_type::value_integer;
8498 }
8499 }
8500 }
8501
8502 // this code is reached if we parse a floating-point number or if an
8503 // integer conversion above failed
8504 strtof(value_float, token_buffer.data(), &endptr);
8505
8506 // we checked the number format before
8507 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8508
8509 return token_type::value_float;
8510 }
8511
8518 token_type scan_literal(const char_type* literal_text, const std::size_t length,
8519 token_type return_type)
8520 {
8521 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8522 for (std::size_t i = 1; i < length; ++i)
8523 {
8524 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8525 {
8526 error_message = "invalid literal";
8527 return token_type::parse_error;
8528 }
8529 }
8530 return return_type;
8531 }
8532
8534 // input management
8536
8538 void reset() noexcept
8539 {
8540 token_buffer.clear();
8541 token_string.clear();
8542 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8543 }
8544
8545 /*
8546 @brief get next character from the input
8547
8548 This function provides the interface to the used input adapter. It does
8549 not throw in case the input reached EOF, but returns a
8550 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8551 for use in error messages.
8552
8553 @return character read from the input
8554 */
8556 {
8557 ++position.chars_read_total;
8558 ++position.chars_read_current_line;
8559
8560 if (next_unget)
8561 {
8562 // just reset the next_unget variable and work with current
8563 next_unget = false;
8564 }
8565 else
8566 {
8567 current = ia.get_character();
8568 }
8569
8570 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8571 {
8572 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8573 }
8574
8575 if (current == '\n')
8576 {
8577 ++position.lines_read;
8578 position.chars_read_current_line = 0;
8579 }
8580
8581 return current;
8582 }
8583
8592 void unget()
8593 {
8594 next_unget = true;
8595
8596 --position.chars_read_total;
8597
8598 // in case we "unget" a newline, we have to also decrement the lines_read
8599 if (position.chars_read_current_line == 0)
8600 {
8601 if (position.lines_read > 0)
8602 {
8603 --position.lines_read;
8604 }
8605 }
8606 else
8607 {
8608 --position.chars_read_current_line;
8609 }
8610
8611 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8612 {
8613 JSON_ASSERT(!token_string.empty());
8614 token_string.pop_back();
8615 }
8616 }
8617
8620 {
8621 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8622 }
8623
8624 public:
8626 // value getters
8628
8630 constexpr number_integer_t get_number_integer() const noexcept
8631 {
8632 return value_integer;
8633 }
8634
8636 constexpr number_unsigned_t get_number_unsigned() const noexcept
8637 {
8638 return value_unsigned;
8639 }
8640
8642 constexpr number_float_t get_number_float() const noexcept
8643 {
8644 return value_float;
8645 }
8646
8649 {
8650 return token_buffer;
8651 }
8652
8654 // diagnostics
8656
8658 constexpr position_t get_position() const noexcept
8659 {
8660 return position;
8661 }
8662
8666 std::string get_token_string() const
8667 {
8668 // escape control characters
8669 std::string result;
8670 for (const auto c : token_string)
8671 {
8672 if (static_cast<unsigned char>(c) <= '\x1F')
8673 {
8674 // escape control characters
8675 std::array<char, 9> cs{{}};
8676 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8677 result += cs.data();
8678 }
8679 else
8680 {
8681 // add character as is
8682 result.push_back(static_cast<std::string::value_type>(c));
8683 }
8684 }
8685
8686 return result;
8687 }
8688
8691 constexpr const char* get_error_message() const noexcept
8692 {
8693 return error_message;
8694 }
8695
8697 // actual scanner
8699
8705 {
8706 if (get() == 0xEF)
8707 {
8708 // check if we completely parse the BOM
8709 return get() == 0xBB && get() == 0xBF;
8710 }
8711
8712 // the first character is not the beginning of the BOM; unget it to
8713 // process is later
8714 unget();
8715 return true;
8716 }
8717
8719 {
8720 do
8721 {
8722 get();
8723 }
8724 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8725 }
8726
8728 {
8729 // initially, skip the BOM
8730 if (position.chars_read_total == 0 && !skip_bom())
8731 {
8732 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8733 return token_type::parse_error;
8734 }
8735
8736 // read next character and ignore whitespace
8737 skip_whitespace();
8738
8739 // ignore comments
8740 while (ignore_comments && current == '/')
8741 {
8742 if (!scan_comment())
8743 {
8744 return token_type::parse_error;
8745 }
8746
8747 // skip following whitespace
8748 skip_whitespace();
8749 }
8750
8751 switch (current)
8752 {
8753 // structural characters
8754 case '[':
8755 return token_type::begin_array;
8756 case ']':
8757 return token_type::end_array;
8758 case '{':
8759 return token_type::begin_object;
8760 case '}':
8761 return token_type::end_object;
8762 case ':':
8763 return token_type::name_separator;
8764 case ',':
8765 return token_type::value_separator;
8766
8767 // literals
8768 case 't':
8769 {
8770 std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
8771 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8772 }
8773 case 'f':
8774 {
8775 std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
8776 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8777 }
8778 case 'n':
8779 {
8780 std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
8781 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8782 }
8783
8784 // string
8785 case '\"':
8786 return scan_string();
8787
8788 // number
8789 case '-':
8790 case '0':
8791 case '1':
8792 case '2':
8793 case '3':
8794 case '4':
8795 case '5':
8796 case '6':
8797 case '7':
8798 case '8':
8799 case '9':
8800 return scan_number();
8801
8802 // end of input (the null byte is needed when parsing from
8803 // string literals)
8804 case '\0':
8805 case std::char_traits<char_type>::eof():
8806 return token_type::end_of_input;
8807
8808 // error
8809 default:
8810 error_message = "invalid literal";
8811 return token_type::parse_error;
8812 }
8813 }
8814
8815 private:
8817 InputAdapterType ia;
8818
8820 const bool ignore_comments = false;
8821
8823 char_int_type current = std::char_traits<char_type>::eof();
8824
8826 bool next_unget = false;
8827
8829 position_t position {};
8830
8832 std::vector<char_type> token_string {};
8833
8835 string_t token_buffer {};
8836
8838 const char* error_message = "";
8839
8840 // number values
8841 number_integer_t value_integer = 0;
8842 number_unsigned_t value_unsigned = 0;
8843 number_float_t value_float = 0;
8844
8846 const char_int_type decimal_point_char = '.';
8847};
8848
8849} // namespace detail
8851
8852// #include <nlohmann/detail/macro_scope.hpp>
8853
8854// #include <nlohmann/detail/meta/is_sax.hpp>
8855// __ _____ _____ _____
8856// __| | __| | | | JSON for Modern C++
8857// | | |__ | | | | | | version 3.11.1
8858// |_____|_____|_____|_|___| https://github.com/nlohmann/json
8859//
8860// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
8861// SPDX-License-Identifier: MIT
8862
8863
8864
8865#include <cstdint> // size_t
8866#include <utility> // declval
8867#include <string> // string
8868
8869// #include <nlohmann/detail/abi_macros.hpp>
8870
8871// #include <nlohmann/detail/meta/detected.hpp>
8872
8873// #include <nlohmann/detail/meta/type_traits.hpp>
8874
8875
8877namespace detail
8878{
8879
8880template<typename T>
8881using null_function_t = decltype(std::declval<T&>().null());
8882
8883template<typename T>
8885 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8886
8887template<typename T, typename Integer>
8889 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8890
8891template<typename T, typename Unsigned>
8893 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8894
8895template<typename T, typename Float, typename String>
8896using number_float_function_t = decltype(std::declval<T&>().number_float(
8897 std::declval<Float>(), std::declval<const String&>()));
8898
8899template<typename T, typename String>
8901 decltype(std::declval<T&>().string(std::declval<String&>()));
8902
8903template<typename T, typename Binary>
8905 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8906
8907template<typename T>
8909 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8910
8911template<typename T, typename String>
8913 decltype(std::declval<T&>().key(std::declval<String&>()));
8914
8915template<typename T>
8916using end_object_function_t = decltype(std::declval<T&>().end_object());
8917
8918template<typename T>
8920 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8921
8922template<typename T>
8923using end_array_function_t = decltype(std::declval<T&>().end_array());
8924
8925template<typename T, typename Exception>
8926using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8927 std::declval<std::size_t>(), std::declval<const std::string&>(),
8928 std::declval<const Exception&>()));
8929
8930template<typename SAX, typename BasicJsonType>
8932{
8933 private:
8935 "BasicJsonType must be of type basic_json<...>");
8936
8937 using number_integer_t = typename BasicJsonType::number_integer_t;
8938 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8939 using number_float_t = typename BasicJsonType::number_float_t;
8940 using string_t = typename BasicJsonType::string_t;
8941 using binary_t = typename BasicJsonType::binary_t;
8942 using exception_t = typename BasicJsonType::exception;
8943
8944 public:
8945 static constexpr bool value =
8959};
8960
8961template<typename SAX, typename BasicJsonType>
8963{
8964 private:
8966 "BasicJsonType must be of type basic_json<...>");
8967
8968 using number_integer_t = typename BasicJsonType::number_integer_t;
8969 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8970 using number_float_t = typename BasicJsonType::number_float_t;
8971 using string_t = typename BasicJsonType::string_t;
8972 using binary_t = typename BasicJsonType::binary_t;
8973 using exception_t = typename BasicJsonType::exception;
8974
8975 public:
8977 "Missing/invalid function: bool null()");
8979 "Missing/invalid function: bool boolean(bool)");
8981 "Missing/invalid function: bool boolean(bool)");
8982 static_assert(
8984 number_integer_t>::value,
8985 "Missing/invalid function: bool number_integer(number_integer_t)");
8986 static_assert(
8988 number_unsigned_t>::value,
8989 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8990 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8991 number_float_t, string_t>::value,
8992 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8993 static_assert(
8995 "Missing/invalid function: bool string(string_t&)");
8996 static_assert(
8998 "Missing/invalid function: bool binary(binary_t&)");
9000 "Missing/invalid function: bool start_object(std::size_t)");
9002 "Missing/invalid function: bool key(string_t&)");
9004 "Missing/invalid function: bool end_object()");
9006 "Missing/invalid function: bool start_array(std::size_t)");
9008 "Missing/invalid function: bool end_array()");
9009 static_assert(
9011 "Missing/invalid function: bool parse_error(std::size_t, const "
9012 "std::string&, const exception&)");
9013};
9014
9015} // namespace detail
9017
9018// #include <nlohmann/detail/meta/type_traits.hpp>
9019
9020// #include <nlohmann/detail/string_concat.hpp>
9021
9022// #include <nlohmann/detail/value_t.hpp>
9023
9024
9026namespace detail
9027{
9028
9031{
9032 error,
9033 ignore,
9034 store
9035};
9036
9044static inline bool little_endianness(int num = 1) noexcept
9045{
9046 return *reinterpret_cast<char*>(&num) == 1;
9047}
9048
9049
9051// binary reader //
9053
9057template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9059{
9060 using number_integer_t = typename BasicJsonType::number_integer_t;
9061 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9062 using number_float_t = typename BasicJsonType::number_float_t;
9063 using string_t = typename BasicJsonType::string_t;
9064 using binary_t = typename BasicJsonType::binary_t;
9065 using json_sax_t = SAX;
9066 using char_type = typename InputAdapterType::char_type;
9067 using char_int_type = typename std::char_traits<char_type>::int_type;
9068
9069 public:
9075 explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9076 {
9078 }
9079
9080 // make class move-only
9082 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9084 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9085 ~binary_reader() = default;
9086
9096 bool sax_parse(const input_format_t format,
9097 json_sax_t* sax_,
9098 const bool strict = true,
9099 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9100 {
9101 sax = sax_;
9102 bool result = false;
9103
9104 switch (format)
9105 {
9106 case input_format_t::bson:
9107 result = parse_bson_internal();
9108 break;
9109
9110 case input_format_t::cbor:
9111 result = parse_cbor_internal(true, tag_handler);
9112 break;
9113
9114 case input_format_t::msgpack:
9115 result = parse_msgpack_internal();
9116 break;
9117
9118 case input_format_t::ubjson:
9119 case input_format_t::bjdata:
9120 result = parse_ubjson_internal();
9121 break;
9122
9123 case input_format_t::json: // LCOV_EXCL_LINE
9124 default: // LCOV_EXCL_LINE
9125 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9126 }
9127
9128 // strict mode: next byte must be EOF
9129 if (result && strict)
9130 {
9131 if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9132 {
9133 get_ignore_noop();
9134 }
9135 else
9136 {
9137 get();
9138 }
9139
9140 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
9141 {
9142 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9143 exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9144 }
9145 }
9146
9147 return result;
9148 }
9149
9150 private:
9152 // BSON //
9154
9160 {
9161 std::int32_t document_size{};
9162 get_number<std::int32_t, true>(input_format_t::bson, document_size);
9163
9164 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
9165 {
9166 return false;
9167 }
9168
9169 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9170 {
9171 return false;
9172 }
9173
9174 return sax->end_object();
9175 }
9176
9185 {
9186 auto out = std::back_inserter(result);
9187 while (true)
9188 {
9189 get();
9190 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
9191 {
9192 return false;
9193 }
9194 if (current == 0x00)
9195 {
9196 return true;
9197 }
9198 *out++ = static_cast<typename string_t::value_type>(current);
9199 }
9200 }
9201
9213 template<typename NumberType>
9214 bool get_bson_string(const NumberType len, string_t& result)
9215 {
9216 if (JSON_HEDLEY_UNLIKELY(len < 1))
9217 {
9218 auto last_token = get_token_string();
9219 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9220 exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
9221 }
9222
9223 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
9224 }
9225
9235 template<typename NumberType>
9236 bool get_bson_binary(const NumberType len, binary_t& result)
9237 {
9238 if (JSON_HEDLEY_UNLIKELY(len < 0))
9239 {
9240 auto last_token = get_token_string();
9241 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9242 exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
9243 }
9244
9245 // All BSON binary values have a subtype
9246 std::uint8_t subtype{};
9247 get_number<std::uint8_t>(input_format_t::bson, subtype);
9248 result.set_subtype(subtype);
9249
9250 return get_binary(input_format_t::bson, len, result);
9251 }
9252
9264 const std::size_t element_type_parse_position)
9265 {
9266 switch (element_type)
9267 {
9268 case 0x01: // double
9269 {
9270 double number{};
9271 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9272 }
9273
9274 case 0x02: // string
9275 {
9276 std::int32_t len{};
9278 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
9279 }
9280
9281 case 0x03: // object
9282 {
9283 return parse_bson_internal();
9284 }
9285
9286 case 0x04: // array
9287 {
9288 return parse_bson_array();
9289 }
9290
9291 case 0x05: // binary
9292 {
9293 std::int32_t len{};
9295 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
9296 }
9297
9298 case 0x08: // boolean
9299 {
9300 return sax->boolean(get() != 0);
9301 }
9302
9303 case 0x0A: // null
9304 {
9305 return sax->null();
9306 }
9307
9308 case 0x10: // int32
9309 {
9310 std::int32_t value{};
9311 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9312 }
9313
9314 case 0x12: // int64
9315 {
9316 std::int64_t value{};
9317 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9318 }
9319
9320 default: // anything else not supported (yet)
9321 {
9322 std::array<char, 3> cr{{}};
9323 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9324 std::string cr_str{cr.data()};
9325 return sax->parse_error(element_type_parse_position, cr_str,
9326 parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9327 }
9328 }
9329 }
9330
9343 bool parse_bson_element_list(const bool is_array)
9344 {
9345 string_t key;
9346
9347 while (auto element_type = get())
9348 {
9349 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
9350 {
9351 return false;
9352 }
9353
9354 const std::size_t element_type_parse_position = chars_read;
9355 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
9356 {
9357 return false;
9358 }
9359
9360 if (!is_array && !sax->key(key))
9361 {
9362 return false;
9363 }
9364
9365 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9366 {
9367 return false;
9368 }
9369
9370 // get_bson_cstr only appends
9371 key.clear();
9372 }
9373
9374 return true;
9375 }
9376
9382 {
9383 std::int32_t document_size{};
9384 get_number<std::int32_t, true>(input_format_t::bson, document_size);
9385
9386 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9387 {
9388 return false;
9389 }
9390
9391 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9392 {
9393 return false;
9394 }
9395
9396 return sax->end_array();
9397 }
9398
9400 // CBOR //
9402
9411 bool parse_cbor_internal(const bool get_char,
9412 const cbor_tag_handler_t tag_handler)
9413 {
9414 switch (get_char ? get() : current)
9415 {
9416 // EOF
9417 case std::char_traits<char_type>::eof():
9418 return unexpect_eof(input_format_t::cbor, "value");
9419
9420 // Integer 0x00..0x17 (0..23)
9421 case 0x00:
9422 case 0x01:
9423 case 0x02:
9424 case 0x03:
9425 case 0x04:
9426 case 0x05:
9427 case 0x06:
9428 case 0x07:
9429 case 0x08:
9430 case 0x09:
9431 case 0x0A:
9432 case 0x0B:
9433 case 0x0C:
9434 case 0x0D:
9435 case 0x0E:
9436 case 0x0F:
9437 case 0x10:
9438 case 0x11:
9439 case 0x12:
9440 case 0x13:
9441 case 0x14:
9442 case 0x15:
9443 case 0x16:
9444 case 0x17:
9445 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9446
9447 case 0x18: // Unsigned integer (one-byte uint8_t follows)
9448 {
9449 std::uint8_t number{};
9450 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9451 }
9452
9453 case 0x19: // Unsigned integer (two-byte uint16_t follows)
9454 {
9455 std::uint16_t number{};
9456 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9457 }
9458
9459 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9460 {
9461 std::uint32_t number{};
9462 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9463 }
9464
9465 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9466 {
9467 std::uint64_t number{};
9468 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9469 }
9470
9471 // Negative integer -1-0x00..-1-0x17 (-1..-24)
9472 case 0x20:
9473 case 0x21:
9474 case 0x22:
9475 case 0x23:
9476 case 0x24:
9477 case 0x25:
9478 case 0x26:
9479 case 0x27:
9480 case 0x28:
9481 case 0x29:
9482 case 0x2A:
9483 case 0x2B:
9484 case 0x2C:
9485 case 0x2D:
9486 case 0x2E:
9487 case 0x2F:
9488 case 0x30:
9489 case 0x31:
9490 case 0x32:
9491 case 0x33:
9492 case 0x34:
9493 case 0x35:
9494 case 0x36:
9495 case 0x37:
9496 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9497
9498 case 0x38: // Negative integer (one-byte uint8_t follows)
9499 {
9500 std::uint8_t number{};
9501 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9502 }
9503
9504 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9505 {
9506 std::uint16_t number{};
9507 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9508 }
9509
9510 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9511 {
9512 std::uint32_t number{};
9513 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9514 }
9515
9516 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9517 {
9518 std::uint64_t number{};
9519 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9520 - static_cast<number_integer_t>(number));
9521 }
9522
9523 // Binary data (0x00..0x17 bytes follow)
9524 case 0x40:
9525 case 0x41:
9526 case 0x42:
9527 case 0x43:
9528 case 0x44:
9529 case 0x45:
9530 case 0x46:
9531 case 0x47:
9532 case 0x48:
9533 case 0x49:
9534 case 0x4A:
9535 case 0x4B:
9536 case 0x4C:
9537 case 0x4D:
9538 case 0x4E:
9539 case 0x4F:
9540 case 0x50:
9541 case 0x51:
9542 case 0x52:
9543 case 0x53:
9544 case 0x54:
9545 case 0x55:
9546 case 0x56:
9547 case 0x57:
9548 case 0x58: // Binary data (one-byte uint8_t for n follows)
9549 case 0x59: // Binary data (two-byte uint16_t for n follow)
9550 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9551 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9552 case 0x5F: // Binary data (indefinite length)
9553 {
9554 binary_t b;
9555 return get_cbor_binary(b) && sax->binary(b);
9556 }
9557
9558 // UTF-8 string (0x00..0x17 bytes follow)
9559 case 0x60:
9560 case 0x61:
9561 case 0x62:
9562 case 0x63:
9563 case 0x64:
9564 case 0x65:
9565 case 0x66:
9566 case 0x67:
9567 case 0x68:
9568 case 0x69:
9569 case 0x6A:
9570 case 0x6B:
9571 case 0x6C:
9572 case 0x6D:
9573 case 0x6E:
9574 case 0x6F:
9575 case 0x70:
9576 case 0x71:
9577 case 0x72:
9578 case 0x73:
9579 case 0x74:
9580 case 0x75:
9581 case 0x76:
9582 case 0x77:
9583 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9584 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9585 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9586 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9587 case 0x7F: // UTF-8 string (indefinite length)
9588 {
9589 string_t s;
9590 return get_cbor_string(s) && sax->string(s);
9591 }
9592
9593 // array (0x00..0x17 data items follow)
9594 case 0x80:
9595 case 0x81:
9596 case 0x82:
9597 case 0x83:
9598 case 0x84:
9599 case 0x85:
9600 case 0x86:
9601 case 0x87:
9602 case 0x88:
9603 case 0x89:
9604 case 0x8A:
9605 case 0x8B:
9606 case 0x8C:
9607 case 0x8D:
9608 case 0x8E:
9609 case 0x8F:
9610 case 0x90:
9611 case 0x91:
9612 case 0x92:
9613 case 0x93:
9614 case 0x94:
9615 case 0x95:
9616 case 0x96:
9617 case 0x97:
9618 return get_cbor_array(
9619 conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9620
9621 case 0x98: // array (one-byte uint8_t for n follows)
9622 {
9623 std::uint8_t len{};
9624 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9625 }
9626
9627 case 0x99: // array (two-byte uint16_t for n follow)
9628 {
9629 std::uint16_t len{};
9630 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9631 }
9632
9633 case 0x9A: // array (four-byte uint32_t for n follow)
9634 {
9635 std::uint32_t len{};
9636 return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9637 }
9638
9639 case 0x9B: // array (eight-byte uint64_t for n follow)
9640 {
9641 std::uint64_t len{};
9642 return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9643 }
9644
9645 case 0x9F: // array (indefinite length)
9646 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9647
9648 // map (0x00..0x17 pairs of data items follow)
9649 case 0xA0:
9650 case 0xA1:
9651 case 0xA2:
9652 case 0xA3:
9653 case 0xA4:
9654 case 0xA5:
9655 case 0xA6:
9656 case 0xA7:
9657 case 0xA8:
9658 case 0xA9:
9659 case 0xAA:
9660 case 0xAB:
9661 case 0xAC:
9662 case 0xAD:
9663 case 0xAE:
9664 case 0xAF:
9665 case 0xB0:
9666 case 0xB1:
9667 case 0xB2:
9668 case 0xB3:
9669 case 0xB4:
9670 case 0xB5:
9671 case 0xB6:
9672 case 0xB7:
9673 return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9674
9675 case 0xB8: // map (one-byte uint8_t for n follows)
9676 {
9677 std::uint8_t len{};
9678 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9679 }
9680
9681 case 0xB9: // map (two-byte uint16_t for n follow)
9682 {
9683 std::uint16_t len{};
9684 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9685 }
9686
9687 case 0xBA: // map (four-byte uint32_t for n follow)
9688 {
9689 std::uint32_t len{};
9690 return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9691 }
9692
9693 case 0xBB: // map (eight-byte uint64_t for n follow)
9694 {
9695 std::uint64_t len{};
9696 return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9697 }
9698
9699 case 0xBF: // map (indefinite length)
9700 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9701
9702 case 0xC6: // tagged item
9703 case 0xC7:
9704 case 0xC8:
9705 case 0xC9:
9706 case 0xCA:
9707 case 0xCB:
9708 case 0xCC:
9709 case 0xCD:
9710 case 0xCE:
9711 case 0xCF:
9712 case 0xD0:
9713 case 0xD1:
9714 case 0xD2:
9715 case 0xD3:
9716 case 0xD4:
9717 case 0xD8: // tagged item (1 bytes follow)
9718 case 0xD9: // tagged item (2 bytes follow)
9719 case 0xDA: // tagged item (4 bytes follow)
9720 case 0xDB: // tagged item (8 bytes follow)
9721 {
9722 switch (tag_handler)
9723 {
9724 case cbor_tag_handler_t::error:
9725 {
9726 auto last_token = get_token_string();
9727 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9728 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9729 }
9730
9731 case cbor_tag_handler_t::ignore:
9732 {
9733 // ignore binary subtype
9734 switch (current)
9735 {
9736 case 0xD8:
9737 {
9738 std::uint8_t subtype_to_ignore{};
9739 get_number(input_format_t::cbor, subtype_to_ignore);
9740 break;
9741 }
9742 case 0xD9:
9743 {
9744 std::uint16_t subtype_to_ignore{};
9745 get_number(input_format_t::cbor, subtype_to_ignore);
9746 break;
9747 }
9748 case 0xDA:
9749 {
9750 std::uint32_t subtype_to_ignore{};
9751 get_number(input_format_t::cbor, subtype_to_ignore);
9752 break;
9753 }
9754 case 0xDB:
9755 {
9756 std::uint64_t subtype_to_ignore{};
9757 get_number(input_format_t::cbor, subtype_to_ignore);
9758 break;
9759 }
9760 default:
9761 break;
9762 }
9763 return parse_cbor_internal(true, tag_handler);
9764 }
9765
9766 case cbor_tag_handler_t::store:
9767 {
9768 binary_t b;
9769 // use binary subtype and store in binary container
9770 switch (current)
9771 {
9772 case 0xD8:
9773 {
9774 std::uint8_t subtype{};
9775 get_number(input_format_t::cbor, subtype);
9776 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9777 break;
9778 }
9779 case 0xD9:
9780 {
9781 std::uint16_t subtype{};
9782 get_number(input_format_t::cbor, subtype);
9783 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9784 break;
9785 }
9786 case 0xDA:
9787 {
9788 std::uint32_t subtype{};
9789 get_number(input_format_t::cbor, subtype);
9790 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9791 break;
9792 }
9793 case 0xDB:
9794 {
9795 std::uint64_t subtype{};
9796 get_number(input_format_t::cbor, subtype);
9797 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9798 break;
9799 }
9800 default:
9801 return parse_cbor_internal(true, tag_handler);
9802 }
9803 get();
9804 return get_cbor_binary(b) && sax->binary(b);
9805 }
9806
9807 default: // LCOV_EXCL_LINE
9808 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9809 return false; // LCOV_EXCL_LINE
9810 }
9811 }
9812
9813 case 0xF4: // false
9814 return sax->boolean(false);
9815
9816 case 0xF5: // true
9817 return sax->boolean(true);
9818
9819 case 0xF6: // null
9820 return sax->null();
9821
9822 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9823 {
9824 const auto byte1_raw = get();
9825 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9826 {
9827 return false;
9828 }
9829 const auto byte2_raw = get();
9830 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9831 {
9832 return false;
9833 }
9834
9835 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9836 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9837
9838 // code from RFC 7049, Appendix D, Figure 3:
9839 // As half-precision floating-point numbers were only added
9840 // to IEEE 754 in 2008, today's programming platforms often
9841 // still only have limited support for them. It is very
9842 // easy to include at least decoding support for them even
9843 // without such support. An example of a small decoder for
9844 // half-precision floating-point numbers in the C language
9845 // is shown in Fig. 3.
9846 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9847 const double val = [&half]
9848 {
9849 const int exp = (half >> 10u) & 0x1Fu;
9850 const unsigned int mant = half & 0x3FFu;
9851 JSON_ASSERT(0 <= exp&& exp <= 32);
9852 JSON_ASSERT(mant <= 1024);
9853 switch (exp)
9854 {
9855 case 0:
9856 return std::ldexp(mant, -24);
9857 case 31:
9858 return (mant == 0)
9859 ? std::numeric_limits<double>::infinity()
9860 : std::numeric_limits<double>::quiet_NaN();
9861 default:
9862 return std::ldexp(mant + 1024, exp - 25);
9863 }
9864 }();
9865 return sax->number_float((half & 0x8000u) != 0
9866 ? static_cast<number_float_t>(-val)
9867 : static_cast<number_float_t>(val), "");
9868 }
9869
9870 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9871 {
9872 float number{};
9873 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9874 }
9875
9876 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9877 {
9878 double number{};
9879 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9880 }
9881
9882 default: // anything else (0xFF is handled inside the other types)
9883 {
9884 auto last_token = get_token_string();
9885 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9886 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9887 }
9888 }
9889 }
9890
9903 {
9904 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9905 {
9906 return false;
9907 }
9908
9909 switch (current)
9910 {
9911 // UTF-8 string (0x00..0x17 bytes follow)
9912 case 0x60:
9913 case 0x61:
9914 case 0x62:
9915 case 0x63:
9916 case 0x64:
9917 case 0x65:
9918 case 0x66:
9919 case 0x67:
9920 case 0x68:
9921 case 0x69:
9922 case 0x6A:
9923 case 0x6B:
9924 case 0x6C:
9925 case 0x6D:
9926 case 0x6E:
9927 case 0x6F:
9928 case 0x70:
9929 case 0x71:
9930 case 0x72:
9931 case 0x73:
9932 case 0x74:
9933 case 0x75:
9934 case 0x76:
9935 case 0x77:
9936 {
9937 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9938 }
9939
9940 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9941 {
9942 std::uint8_t len{};
9943 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9944 }
9945
9946 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9947 {
9948 std::uint16_t len{};
9949 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9950 }
9951
9952 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9953 {
9954 std::uint32_t len{};
9955 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9956 }
9957
9958 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9959 {
9960 std::uint64_t len{};
9961 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9962 }
9963
9964 case 0x7F: // UTF-8 string (indefinite length)
9965 {
9966 while (get() != 0xFF)
9967 {
9968 string_t chunk;
9969 if (!get_cbor_string(chunk))
9970 {
9971 return false;
9972 }
9973 result.append(chunk);
9974 }
9975 return true;
9976 }
9977
9978 default:
9979 {
9980 auto last_token = get_token_string();
9981 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9982 exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
9983 }
9984 }
9985 }
9986
9999 {
10000 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10001 {
10002 return false;
10003 }
10004
10005 switch (current)
10006 {
10007 // Binary data (0x00..0x17 bytes follow)
10008 case 0x40:
10009 case 0x41:
10010 case 0x42:
10011 case 0x43:
10012 case 0x44:
10013 case 0x45:
10014 case 0x46:
10015 case 0x47:
10016 case 0x48:
10017 case 0x49:
10018 case 0x4A:
10019 case 0x4B:
10020 case 0x4C:
10021 case 0x4D:
10022 case 0x4E:
10023 case 0x4F:
10024 case 0x50:
10025 case 0x51:
10026 case 0x52:
10027 case 0x53:
10028 case 0x54:
10029 case 0x55:
10030 case 0x56:
10031 case 0x57:
10032 {
10033 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10034 }
10035
10036 case 0x58: // Binary data (one-byte uint8_t for n follows)
10037 {
10038 std::uint8_t len{};
10039 return get_number(input_format_t::cbor, len) &&
10040 get_binary(input_format_t::cbor, len, result);
10041 }
10042
10043 case 0x59: // Binary data (two-byte uint16_t for n follow)
10044 {
10045 std::uint16_t len{};
10046 return get_number(input_format_t::cbor, len) &&
10047 get_binary(input_format_t::cbor, len, result);
10048 }
10049
10050 case 0x5A: // Binary data (four-byte uint32_t for n follow)
10051 {
10052 std::uint32_t len{};
10053 return get_number(input_format_t::cbor, len) &&
10054 get_binary(input_format_t::cbor, len, result);
10055 }
10056
10057 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10058 {
10059 std::uint64_t len{};
10060 return get_number(input_format_t::cbor, len) &&
10061 get_binary(input_format_t::cbor, len, result);
10062 }
10063
10064 case 0x5F: // Binary data (indefinite length)
10065 {
10066 while (get() != 0xFF)
10067 {
10068 binary_t chunk;
10069 if (!get_cbor_binary(chunk))
10070 {
10071 return false;
10072 }
10073 result.insert(result.end(), chunk.begin(), chunk.end());
10074 }
10075 return true;
10076 }
10077
10078 default:
10079 {
10080 auto last_token = get_token_string();
10081 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10082 exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
10083 }
10084 }
10085 }
10086
10093 bool get_cbor_array(const std::size_t len,
10094 const cbor_tag_handler_t tag_handler)
10095 {
10096 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10097 {
10098 return false;
10099 }
10100
10101 if (len != static_cast<std::size_t>(-1))
10102 {
10103 for (std::size_t i = 0; i < len; ++i)
10104 {
10105 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10106 {
10107 return false;
10108 }
10109 }
10110 }
10111 else
10112 {
10113 while (get() != 0xFF)
10114 {
10115 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10116 {
10117 return false;
10118 }
10119 }
10120 }
10121
10122 return sax->end_array();
10123 }
10124
10131 bool get_cbor_object(const std::size_t len,
10132 const cbor_tag_handler_t tag_handler)
10133 {
10134 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10135 {
10136 return false;
10137 }
10138
10139 if (len != 0)
10140 {
10141 string_t key;
10142 if (len != static_cast<std::size_t>(-1))
10143 {
10144 for (std::size_t i = 0; i < len; ++i)
10145 {
10146 get();
10147 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10148 {
10149 return false;
10150 }
10151
10152 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10153 {
10154 return false;
10155 }
10156 key.clear();
10157 }
10158 }
10159 else
10160 {
10161 while (get() != 0xFF)
10162 {
10163 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10164 {
10165 return false;
10166 }
10167
10168 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10169 {
10170 return false;
10171 }
10172 key.clear();
10173 }
10174 }
10175 }
10176
10177 return sax->end_object();
10178 }
10179
10181 // MsgPack //
10183
10188 {
10189 switch (get())
10190 {
10191 // EOF
10192 case std::char_traits<char_type>::eof():
10193 return unexpect_eof(input_format_t::msgpack, "value");
10194
10195 // positive fixint
10196 case 0x00:
10197 case 0x01:
10198 case 0x02:
10199 case 0x03:
10200 case 0x04:
10201 case 0x05:
10202 case 0x06:
10203 case 0x07:
10204 case 0x08:
10205 case 0x09:
10206 case 0x0A:
10207 case 0x0B:
10208 case 0x0C:
10209 case 0x0D:
10210 case 0x0E:
10211 case 0x0F:
10212 case 0x10:
10213 case 0x11:
10214 case 0x12:
10215 case 0x13:
10216 case 0x14:
10217 case 0x15:
10218 case 0x16:
10219 case 0x17:
10220 case 0x18:
10221 case 0x19:
10222 case 0x1A:
10223 case 0x1B:
10224 case 0x1C:
10225 case 0x1D:
10226 case 0x1E:
10227 case 0x1F:
10228 case 0x20:
10229 case 0x21:
10230 case 0x22:
10231 case 0x23:
10232 case 0x24:
10233 case 0x25:
10234 case 0x26:
10235 case 0x27:
10236 case 0x28:
10237 case 0x29:
10238 case 0x2A:
10239 case 0x2B:
10240 case 0x2C:
10241 case 0x2D:
10242 case 0x2E:
10243 case 0x2F:
10244 case 0x30:
10245 case 0x31:
10246 case 0x32:
10247 case 0x33:
10248 case 0x34:
10249 case 0x35:
10250 case 0x36:
10251 case 0x37:
10252 case 0x38:
10253 case 0x39:
10254 case 0x3A:
10255 case 0x3B:
10256 case 0x3C:
10257 case 0x3D:
10258 case 0x3E:
10259 case 0x3F:
10260 case 0x40:
10261 case 0x41:
10262 case 0x42:
10263 case 0x43:
10264 case 0x44:
10265 case 0x45:
10266 case 0x46:
10267 case 0x47:
10268 case 0x48:
10269 case 0x49:
10270 case 0x4A:
10271 case 0x4B:
10272 case 0x4C:
10273 case 0x4D:
10274 case 0x4E:
10275 case 0x4F:
10276 case 0x50:
10277 case 0x51:
10278 case 0x52:
10279 case 0x53:
10280 case 0x54:
10281 case 0x55:
10282 case 0x56:
10283 case 0x57:
10284 case 0x58:
10285 case 0x59:
10286 case 0x5A:
10287 case 0x5B:
10288 case 0x5C:
10289 case 0x5D:
10290 case 0x5E:
10291 case 0x5F:
10292 case 0x60:
10293 case 0x61:
10294 case 0x62:
10295 case 0x63:
10296 case 0x64:
10297 case 0x65:
10298 case 0x66:
10299 case 0x67:
10300 case 0x68:
10301 case 0x69:
10302 case 0x6A:
10303 case 0x6B:
10304 case 0x6C:
10305 case 0x6D:
10306 case 0x6E:
10307 case 0x6F:
10308 case 0x70:
10309 case 0x71:
10310 case 0x72:
10311 case 0x73:
10312 case 0x74:
10313 case 0x75:
10314 case 0x76:
10315 case 0x77:
10316 case 0x78:
10317 case 0x79:
10318 case 0x7A:
10319 case 0x7B:
10320 case 0x7C:
10321 case 0x7D:
10322 case 0x7E:
10323 case 0x7F:
10324 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10325
10326 // fixmap
10327 case 0x80:
10328 case 0x81:
10329 case 0x82:
10330 case 0x83:
10331 case 0x84:
10332 case 0x85:
10333 case 0x86:
10334 case 0x87:
10335 case 0x88:
10336 case 0x89:
10337 case 0x8A:
10338 case 0x8B:
10339 case 0x8C:
10340 case 0x8D:
10341 case 0x8E:
10342 case 0x8F:
10343 return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10344
10345 // fixarray
10346 case 0x90:
10347 case 0x91:
10348 case 0x92:
10349 case 0x93:
10350 case 0x94:
10351 case 0x95:
10352 case 0x96:
10353 case 0x97:
10354 case 0x98:
10355 case 0x99:
10356 case 0x9A:
10357 case 0x9B:
10358 case 0x9C:
10359 case 0x9D:
10360 case 0x9E:
10361 case 0x9F:
10362 return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10363
10364 // fixstr
10365 case 0xA0:
10366 case 0xA1:
10367 case 0xA2:
10368 case 0xA3:
10369 case 0xA4:
10370 case 0xA5:
10371 case 0xA6:
10372 case 0xA7:
10373 case 0xA8:
10374 case 0xA9:
10375 case 0xAA:
10376 case 0xAB:
10377 case 0xAC:
10378 case 0xAD:
10379 case 0xAE:
10380 case 0xAF:
10381 case 0xB0:
10382 case 0xB1:
10383 case 0xB2:
10384 case 0xB3:
10385 case 0xB4:
10386 case 0xB5:
10387 case 0xB6:
10388 case 0xB7:
10389 case 0xB8:
10390 case 0xB9:
10391 case 0xBA:
10392 case 0xBB:
10393 case 0xBC:
10394 case 0xBD:
10395 case 0xBE:
10396 case 0xBF:
10397 case 0xD9: // str 8
10398 case 0xDA: // str 16
10399 case 0xDB: // str 32
10400 {
10401 string_t s;
10402 return get_msgpack_string(s) && sax->string(s);
10403 }
10404
10405 case 0xC0: // nil
10406 return sax->null();
10407
10408 case 0xC2: // false
10409 return sax->boolean(false);
10410
10411 case 0xC3: // true
10412 return sax->boolean(true);
10413
10414 case 0xC4: // bin 8
10415 case 0xC5: // bin 16
10416 case 0xC6: // bin 32
10417 case 0xC7: // ext 8
10418 case 0xC8: // ext 16
10419 case 0xC9: // ext 32
10420 case 0xD4: // fixext 1
10421 case 0xD5: // fixext 2
10422 case 0xD6: // fixext 4
10423 case 0xD7: // fixext 8
10424 case 0xD8: // fixext 16
10425 {
10426 binary_t b;
10427 return get_msgpack_binary(b) && sax->binary(b);
10428 }
10429
10430 case 0xCA: // float 32
10431 {
10432 float number{};
10433 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10434 }
10435
10436 case 0xCB: // float 64
10437 {
10438 double number{};
10439 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10440 }
10441
10442 case 0xCC: // uint 8
10443 {
10444 std::uint8_t number{};
10445 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10446 }
10447
10448 case 0xCD: // uint 16
10449 {
10450 std::uint16_t number{};
10451 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10452 }
10453
10454 case 0xCE: // uint 32
10455 {
10456 std::uint32_t number{};
10457 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10458 }
10459
10460 case 0xCF: // uint 64
10461 {
10462 std::uint64_t number{};
10463 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10464 }
10465
10466 case 0xD0: // int 8
10467 {
10468 std::int8_t number{};
10469 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10470 }
10471
10472 case 0xD1: // int 16
10473 {
10474 std::int16_t number{};
10475 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10476 }
10477
10478 case 0xD2: // int 32
10479 {
10480 std::int32_t number{};
10481 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10482 }
10483
10484 case 0xD3: // int 64
10485 {
10486 std::int64_t number{};
10487 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10488 }
10489
10490 case 0xDC: // array 16
10491 {
10492 std::uint16_t len{};
10493 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10494 }
10495
10496 case 0xDD: // array 32
10497 {
10498 std::uint32_t len{};
10499 return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
10500 }
10501
10502 case 0xDE: // map 16
10503 {
10504 std::uint16_t len{};
10505 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10506 }
10507
10508 case 0xDF: // map 32
10509 {
10510 std::uint32_t len{};
10511 return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
10512 }
10513
10514 // negative fixint
10515 case 0xE0:
10516 case 0xE1:
10517 case 0xE2:
10518 case 0xE3:
10519 case 0xE4:
10520 case 0xE5:
10521 case 0xE6:
10522 case 0xE7:
10523 case 0xE8:
10524 case 0xE9:
10525 case 0xEA:
10526 case 0xEB:
10527 case 0xEC:
10528 case 0xED:
10529 case 0xEE:
10530 case 0xEF:
10531 case 0xF0:
10532 case 0xF1:
10533 case 0xF2:
10534 case 0xF3:
10535 case 0xF4:
10536 case 0xF5:
10537 case 0xF6:
10538 case 0xF7:
10539 case 0xF8:
10540 case 0xF9:
10541 case 0xFA:
10542 case 0xFB:
10543 case 0xFC:
10544 case 0xFD:
10545 case 0xFE:
10546 case 0xFF:
10547 return sax->number_integer(static_cast<std::int8_t>(current));
10548
10549 default: // anything else
10550 {
10551 auto last_token = get_token_string();
10552 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10553 exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10554 }
10555 }
10556 }
10557
10569 {
10570 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10571 {
10572 return false;
10573 }
10574
10575 switch (current)
10576 {
10577 // fixstr
10578 case 0xA0:
10579 case 0xA1:
10580 case 0xA2:
10581 case 0xA3:
10582 case 0xA4:
10583 case 0xA5:
10584 case 0xA6:
10585 case 0xA7:
10586 case 0xA8:
10587 case 0xA9:
10588 case 0xAA:
10589 case 0xAB:
10590 case 0xAC:
10591 case 0xAD:
10592 case 0xAE:
10593 case 0xAF:
10594 case 0xB0:
10595 case 0xB1:
10596 case 0xB2:
10597 case 0xB3:
10598 case 0xB4:
10599 case 0xB5:
10600 case 0xB6:
10601 case 0xB7:
10602 case 0xB8:
10603 case 0xB9:
10604 case 0xBA:
10605 case 0xBB:
10606 case 0xBC:
10607 case 0xBD:
10608 case 0xBE:
10609 case 0xBF:
10610 {
10611 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10612 }
10613
10614 case 0xD9: // str 8
10615 {
10616 std::uint8_t len{};
10617 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10618 }
10619
10620 case 0xDA: // str 16
10621 {
10622 std::uint16_t len{};
10623 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10624 }
10625
10626 case 0xDB: // str 32
10627 {
10628 std::uint32_t len{};
10629 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10630 }
10631
10632 default:
10633 {
10634 auto last_token = get_token_string();
10635 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10636 exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10637 }
10638 }
10639 }
10640
10652 {
10653 // helper function to set the subtype
10654 auto assign_and_return_true = [&result](std::int8_t subtype)
10655 {
10656 result.set_subtype(static_cast<std::uint8_t>(subtype));
10657 return true;
10658 };
10659
10660 switch (current)
10661 {
10662 case 0xC4: // bin 8
10663 {
10664 std::uint8_t len{};
10665 return get_number(input_format_t::msgpack, len) &&
10666 get_binary(input_format_t::msgpack, len, result);
10667 }
10668
10669 case 0xC5: // bin 16
10670 {
10671 std::uint16_t len{};
10672 return get_number(input_format_t::msgpack, len) &&
10673 get_binary(input_format_t::msgpack, len, result);
10674 }
10675
10676 case 0xC6: // bin 32
10677 {
10678 std::uint32_t len{};
10679 return get_number(input_format_t::msgpack, len) &&
10680 get_binary(input_format_t::msgpack, len, result);
10681 }
10682
10683 case 0xC7: // ext 8
10684 {
10685 std::uint8_t len{};
10686 std::int8_t subtype{};
10687 return get_number(input_format_t::msgpack, len) &&
10688 get_number(input_format_t::msgpack, subtype) &&
10689 get_binary(input_format_t::msgpack, len, result) &&
10690 assign_and_return_true(subtype);
10691 }
10692
10693 case 0xC8: // ext 16
10694 {
10695 std::uint16_t len{};
10696 std::int8_t subtype{};
10697 return get_number(input_format_t::msgpack, len) &&
10698 get_number(input_format_t::msgpack, subtype) &&
10699 get_binary(input_format_t::msgpack, len, result) &&
10700 assign_and_return_true(subtype);
10701 }
10702
10703 case 0xC9: // ext 32
10704 {
10705 std::uint32_t len{};
10706 std::int8_t subtype{};
10707 return get_number(input_format_t::msgpack, len) &&
10708 get_number(input_format_t::msgpack, subtype) &&
10709 get_binary(input_format_t::msgpack, len, result) &&
10710 assign_and_return_true(subtype);
10711 }
10712
10713 case 0xD4: // fixext 1
10714 {
10715 std::int8_t subtype{};
10716 return get_number(input_format_t::msgpack, subtype) &&
10717 get_binary(input_format_t::msgpack, 1, result) &&
10718 assign_and_return_true(subtype);
10719 }
10720
10721 case 0xD5: // fixext 2
10722 {
10723 std::int8_t subtype{};
10724 return get_number(input_format_t::msgpack, subtype) &&
10725 get_binary(input_format_t::msgpack, 2, result) &&
10726 assign_and_return_true(subtype);
10727 }
10728
10729 case 0xD6: // fixext 4
10730 {
10731 std::int8_t subtype{};
10732 return get_number(input_format_t::msgpack, subtype) &&
10733 get_binary(input_format_t::msgpack, 4, result) &&
10734 assign_and_return_true(subtype);
10735 }
10736
10737 case 0xD7: // fixext 8
10738 {
10739 std::int8_t subtype{};
10740 return get_number(input_format_t::msgpack, subtype) &&
10741 get_binary(input_format_t::msgpack, 8, result) &&
10742 assign_and_return_true(subtype);
10743 }
10744
10745 case 0xD8: // fixext 16
10746 {
10747 std::int8_t subtype{};
10748 return get_number(input_format_t::msgpack, subtype) &&
10749 get_binary(input_format_t::msgpack, 16, result) &&
10750 assign_and_return_true(subtype);
10751 }
10752
10753 default: // LCOV_EXCL_LINE
10754 return false; // LCOV_EXCL_LINE
10755 }
10756 }
10757
10762 bool get_msgpack_array(const std::size_t len)
10763 {
10764 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10765 {
10766 return false;
10767 }
10768
10769 for (std::size_t i = 0; i < len; ++i)
10770 {
10771 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10772 {
10773 return false;
10774 }
10775 }
10776
10777 return sax->end_array();
10778 }
10779
10784 bool get_msgpack_object(const std::size_t len)
10785 {
10786 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10787 {
10788 return false;
10789 }
10790
10791 string_t key;
10792 for (std::size_t i = 0; i < len; ++i)
10793 {
10794 get();
10795 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10796 {
10797 return false;
10798 }
10799
10800 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10801 {
10802 return false;
10803 }
10804 key.clear();
10805 }
10806
10807 return sax->end_object();
10808 }
10809
10811 // UBJSON //
10813
10821 bool parse_ubjson_internal(const bool get_char = true)
10822 {
10823 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10824 }
10825
10840 bool get_ubjson_string(string_t& result, const bool get_char = true)
10841 {
10842 if (get_char)
10843 {
10844 get(); // TODO(niels): may we ignore N here?
10845 }
10846
10847 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10848 {
10849 return false;
10850 }
10851
10852 switch (current)
10853 {
10854 case 'U':
10855 {
10856 std::uint8_t len{};
10857 return get_number(input_format, len) && get_string(input_format, len, result);
10858 }
10859
10860 case 'i':
10861 {
10862 std::int8_t len{};
10863 return get_number(input_format, len) && get_string(input_format, len, result);
10864 }
10865
10866 case 'I':
10867 {
10868 std::int16_t len{};
10869 return get_number(input_format, len) && get_string(input_format, len, result);
10870 }
10871
10872 case 'l':
10873 {
10874 std::int32_t len{};
10875 return get_number(input_format, len) && get_string(input_format, len, result);
10876 }
10877
10878 case 'L':
10879 {
10880 std::int64_t len{};
10881 return get_number(input_format, len) && get_string(input_format, len, result);
10882 }
10883
10884 case 'u':
10885 {
10886 if (input_format != input_format_t::bjdata)
10887 {
10888 break;
10889 }
10890 std::uint16_t len{};
10891 return get_number(input_format, len) && get_string(input_format, len, result);
10892 }
10893
10894 case 'm':
10895 {
10896 if (input_format != input_format_t::bjdata)
10897 {
10898 break;
10899 }
10900 std::uint32_t len{};
10901 return get_number(input_format, len) && get_string(input_format, len, result);
10902 }
10903
10904 case 'M':
10905 {
10906 if (input_format != input_format_t::bjdata)
10907 {
10908 break;
10909 }
10910 std::uint64_t len{};
10911 return get_number(input_format, len) && get_string(input_format, len, result);
10912 }
10913
10914 default:
10915 break;
10916 }
10917 auto last_token = get_token_string();
10918 std::string message;
10919
10920 if (input_format != input_format_t::bjdata)
10921 {
10922 message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
10923 }
10924 else
10925 {
10926 message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
10927 }
10928 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
10929 }
10930
10935 bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
10936 {
10937 std::pair<std::size_t, char_int_type> size_and_type;
10938 size_t dimlen = 0;
10939 bool no_ndarray = true;
10940
10941 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
10942 {
10943 return false;
10944 }
10945
10946 if (size_and_type.first != string_t::npos)
10947 {
10948 if (size_and_type.second != 0)
10949 {
10950 if (size_and_type.second != 'N')
10951 {
10952 for (std::size_t i = 0; i < size_and_type.first; ++i)
10953 {
10954 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
10955 {
10956 return false;
10957 }
10958 dim.push_back(dimlen);
10959 }
10960 }
10961 }
10962 else
10963 {
10964 for (std::size_t i = 0; i < size_and_type.first; ++i)
10965 {
10966 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
10967 {
10968 return false;
10969 }
10970 dim.push_back(dimlen);
10971 }
10972 }
10973 }
10974 else
10975 {
10976 while (current != ']')
10977 {
10978 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
10979 {
10980 return false;
10981 }
10982 dim.push_back(dimlen);
10983 get_ignore_noop();
10984 }
10985 }
10986 return true;
10987 }
10988
11000 bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11001 {
11002 if (prefix == 0)
11003 {
11004 prefix = get_ignore_noop();
11005 }
11006
11007 switch (prefix)
11008 {
11009 case 'U':
11010 {
11011 std::uint8_t number{};
11012 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11013 {
11014 return false;
11015 }
11016 result = static_cast<std::size_t>(number);
11017 return true;
11018 }
11019
11020 case 'i':
11021 {
11022 std::int8_t number{};
11023 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11024 {
11025 return false;
11026 }
11027 if (number < 0)
11028 {
11029 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11030 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11031 }
11032 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11033 return true;
11034 }
11035
11036 case 'I':
11037 {
11038 std::int16_t number{};
11039 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11040 {
11041 return false;
11042 }
11043 if (number < 0)
11044 {
11045 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11046 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11047 }
11048 result = static_cast<std::size_t>(number);
11049 return true;
11050 }
11051
11052 case 'l':
11053 {
11054 std::int32_t number{};
11055 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11056 {
11057 return false;
11058 }
11059 if (number < 0)
11060 {
11061 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11062 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11063 }
11064 result = static_cast<std::size_t>(number);
11065 return true;
11066 }
11067
11068 case 'L':
11069 {
11070 std::int64_t number{};
11071 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11072 {
11073 return false;
11074 }
11075 if (number < 0)
11076 {
11077 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11078 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11079 }
11080 if (!value_in_range_of<std::size_t>(number))
11081 {
11082 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11083 exception_message(input_format, "integer value overflow", "size"), nullptr));
11084 }
11085 result = static_cast<std::size_t>(number);
11086 return true;
11087 }
11088
11089 case 'u':
11090 {
11091 if (input_format != input_format_t::bjdata)
11092 {
11093 break;
11094 }
11095 std::uint16_t number{};
11096 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11097 {
11098 return false;
11099 }
11100 result = static_cast<std::size_t>(number);
11101 return true;
11102 }
11103
11104 case 'm':
11105 {
11106 if (input_format != input_format_t::bjdata)
11107 {
11108 break;
11109 }
11110 std::uint32_t number{};
11111 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11112 {
11113 return false;
11114 }
11115 result = conditional_static_cast<std::size_t>(number);
11116 return true;
11117 }
11118
11119 case 'M':
11120 {
11121 if (input_format != input_format_t::bjdata)
11122 {
11123 break;
11124 }
11125 std::uint64_t number{};
11126 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11127 {
11128 return false;
11129 }
11130 if (!value_in_range_of<std::size_t>(number))
11131 {
11132 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11133 exception_message(input_format, "integer value overflow", "size"), nullptr));
11134 }
11135 result = detail::conditional_static_cast<std::size_t>(number);
11136 return true;
11137 }
11138
11139 case '[':
11140 {
11141 if (input_format != input_format_t::bjdata)
11142 {
11143 break;
11144 }
11145 if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11146 {
11147 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimentional vector is not allowed", "size"), nullptr));
11148 }
11149 std::vector<size_t> dim;
11150 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11151 {
11152 return false;
11153 }
11154 if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11155 {
11156 result = dim.at(dim.size() - 1);
11157 return true;
11158 }
11159 if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11160 {
11161 for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11162 {
11163 if ( i == 0 )
11164 {
11165 result = 0;
11166 return true;
11167 }
11168 }
11169
11170 string_t key = "_ArraySize_";
11171 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11172 {
11173 return false;
11174 }
11175 result = 1;
11176 for (auto i : dim)
11177 {
11178 result *= i;
11179 if (result == 0 || result == string_t::npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be string_t::npos as it is used to initialize size in get_ubjson_size_type()
11180 {
11181 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
11182 }
11183 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11184 {
11185 return false;
11186 }
11187 }
11188 is_ndarray = true;
11189 return sax->end_array();
11190 }
11191 result = 0;
11192 return true;
11193 }
11194
11195 default:
11196 break;
11197 }
11198 auto last_token = get_token_string();
11199 std::string message;
11200
11201 if (input_format != input_format_t::bjdata)
11202 {
11203 message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11204 }
11205 else
11206 {
11207 message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
11208 }
11209 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
11210 }
11211
11223 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
11224 {
11225 result.first = string_t::npos; // size
11226 result.second = 0; // type
11227 bool is_ndarray = false;
11228
11229 get_ignore_noop();
11230
11231 if (current == '$')
11232 {
11233 std::vector<char_int_type> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
11234
11235 result.second = get(); // must not ignore 'N', because 'N' maybe the type
11236 if (JSON_HEDLEY_UNLIKELY( input_format == input_format_t::bjdata && std::find(bjdx.begin(), bjdx.end(), result.second) != bjdx.end() ))
11237 {
11238 auto last_token = get_token_string();
11239 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11240 exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
11241 }
11242
11243 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
11244 {
11245 return false;
11246 }
11247
11248 get_ignore_noop();
11249 if (JSON_HEDLEY_UNLIKELY(current != '#'))
11250 {
11251 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11252 {
11253 return false;
11254 }
11255 auto last_token = get_token_string();
11256 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11257 exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
11258 }
11259
11260 bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11261 if (input_format == input_format_t::bjdata && is_ndarray)
11262 {
11263 if (inside_ndarray)
11264 {
11265 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11266 exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
11267 }
11268 result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
11269 }
11270 return is_error;
11271 }
11272
11273 if (current == '#')
11274 {
11275 bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11276 if (input_format == input_format_t::bjdata && is_ndarray)
11277 {
11278 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11279 exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
11280 }
11281 return is_error;
11282 }
11283
11284 return true;
11285 }
11286
11292 {
11293 switch (prefix)
11294 {
11295 case std::char_traits<char_type>::eof(): // EOF
11296 return unexpect_eof(input_format, "value");
11297
11298 case 'T': // true
11299 return sax->boolean(true);
11300 case 'F': // false
11301 return sax->boolean(false);
11302
11303 case 'Z': // null
11304 return sax->null();
11305
11306 case 'U':
11307 {
11308 std::uint8_t number{};
11309 return get_number(input_format, number) && sax->number_unsigned(number);
11310 }
11311
11312 case 'i':
11313 {
11314 std::int8_t number{};
11315 return get_number(input_format, number) && sax->number_integer(number);
11316 }
11317
11318 case 'I':
11319 {
11320 std::int16_t number{};
11321 return get_number(input_format, number) && sax->number_integer(number);
11322 }
11323
11324 case 'l':
11325 {
11326 std::int32_t number{};
11327 return get_number(input_format, number) && sax->number_integer(number);
11328 }
11329
11330 case 'L':
11331 {
11332 std::int64_t number{};
11333 return get_number(input_format, number) && sax->number_integer(number);
11334 }
11335
11336 case 'u':
11337 {
11338 if (input_format != input_format_t::bjdata)
11339 {
11340 break;
11341 }
11342 std::uint16_t number{};
11343 return get_number(input_format, number) && sax->number_unsigned(number);
11344 }
11345
11346 case 'm':
11347 {
11348 if (input_format != input_format_t::bjdata)
11349 {
11350 break;
11351 }
11352 std::uint32_t number{};
11353 return get_number(input_format, number) && sax->number_unsigned(number);
11354 }
11355
11356 case 'M':
11357 {
11358 if (input_format != input_format_t::bjdata)
11359 {
11360 break;
11361 }
11362 std::uint64_t number{};
11363 return get_number(input_format, number) && sax->number_unsigned(number);
11364 }
11365
11366 case 'h':
11367 {
11368 if (input_format != input_format_t::bjdata)
11369 {
11370 break;
11371 }
11372 const auto byte1_raw = get();
11373 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11374 {
11375 return false;
11376 }
11377 const auto byte2_raw = get();
11378 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11379 {
11380 return false;
11381 }
11382
11383 const auto byte1 = static_cast<unsigned char>(byte1_raw);
11384 const auto byte2 = static_cast<unsigned char>(byte2_raw);
11385
11386 // code from RFC 7049, Appendix D, Figure 3:
11387 // As half-precision floating-point numbers were only added
11388 // to IEEE 754 in 2008, today's programming platforms often
11389 // still only have limited support for them. It is very
11390 // easy to include at least decoding support for them even
11391 // without such support. An example of a small decoder for
11392 // half-precision floating-point numbers in the C language
11393 // is shown in Fig. 3.
11394 const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11395 const double val = [&half]
11396 {
11397 const int exp = (half >> 10u) & 0x1Fu;
11398 const unsigned int mant = half & 0x3FFu;
11399 JSON_ASSERT(0 <= exp&& exp <= 32);
11400 JSON_ASSERT(mant <= 1024);
11401 switch (exp)
11402 {
11403 case 0:
11404 return std::ldexp(mant, -24);
11405 case 31:
11406 return (mant == 0)
11407 ? std::numeric_limits<double>::infinity()
11408 : std::numeric_limits<double>::quiet_NaN();
11409 default:
11410 return std::ldexp(mant + 1024, exp - 25);
11411 }
11412 }();
11413 return sax->number_float((half & 0x8000u) != 0
11414 ? static_cast<number_float_t>(-val)
11415 : static_cast<number_float_t>(val), "");
11416 }
11417
11418 case 'd':
11419 {
11420 float number{};
11421 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11422 }
11423
11424 case 'D':
11425 {
11426 double number{};
11427 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11428 }
11429
11430 case 'H':
11431 {
11432 return get_ubjson_high_precision_number();
11433 }
11434
11435 case 'C': // char
11436 {
11437 get();
11438 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11439 {
11440 return false;
11441 }
11442 if (JSON_HEDLEY_UNLIKELY(current > 127))
11443 {
11444 auto last_token = get_token_string();
11445 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11446 exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11447 }
11448 string_t s(1, static_cast<typename string_t::value_type>(current));
11449 return sax->string(s);
11450 }
11451
11452 case 'S': // string
11453 {
11454 string_t s;
11455 return get_ubjson_string(s) && sax->string(s);
11456 }
11457
11458 case '[': // array
11459 return get_ubjson_array();
11460
11461 case '{': // object
11462 return get_ubjson_object();
11463
11464 default: // anything else
11465 break;
11466 }
11467 auto last_token = get_token_string();
11468 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
11469 }
11470
11475 {
11476 std::pair<std::size_t, char_int_type> size_and_type;
11477 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11478 {
11479 return false;
11480 }
11481
11482 // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
11483 // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11484
11485 if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && (size_and_type.second & (1 << 8)) != 0)
11486 {
11487 std::map<char_int_type, string_t> bjdtype = {{'U', "uint8"}, {'i', "int8"}, {'u', "uint16"}, {'I', "int16"},
11488 {'m', "uint32"}, {'l', "int32"}, {'M', "uint64"}, {'L', "int64"}, {'d', "single"}, {'D', "double"}, {'C', "char"}
11489 };
11490
11491 size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
11492
11493 string_t key = "_ArrayType_";
11494 if (JSON_HEDLEY_UNLIKELY(bjdtype.count(size_and_type.second) == 0))
11495 {
11496 auto last_token = get_token_string();
11497 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11498 exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11499 }
11500
11501 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(bjdtype[size_and_type.second]) ))
11502 {
11503 return false;
11504 }
11505
11506 if (size_and_type.second == 'C')
11507 {
11508 size_and_type.second = 'U';
11509 }
11510
11511 key = "_ArrayData_";
11512 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
11513 {
11514 return false;
11515 }
11516
11517 for (std::size_t i = 0; i < size_and_type.first; ++i)
11518 {
11519 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11520 {
11521 return false;
11522 }
11523 }
11524
11525 return (sax->end_array() && sax->end_object());
11526 }
11527
11528 if (size_and_type.first != string_t::npos)
11529 {
11530 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11531 {
11532 return false;
11533 }
11534
11535 if (size_and_type.second != 0)
11536 {
11537 if (size_and_type.second != 'N')
11538 {
11539 for (std::size_t i = 0; i < size_and_type.first; ++i)
11540 {
11541 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11542 {
11543 return false;
11544 }
11545 }
11546 }
11547 }
11548 else
11549 {
11550 for (std::size_t i = 0; i < size_and_type.first; ++i)
11551 {
11552 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11553 {
11554 return false;
11555 }
11556 }
11557 }
11558 }
11559 else
11560 {
11561 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11562 {
11563 return false;
11564 }
11565
11566 while (current != ']')
11567 {
11568 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11569 {
11570 return false;
11571 }
11572 get_ignore_noop();
11573 }
11574 }
11575
11576 return sax->end_array();
11577 }
11578
11583 {
11584 std::pair<std::size_t, char_int_type> size_and_type;
11585 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11586 {
11587 return false;
11588 }
11589
11590 // do not accept ND-array size in objects in BJData
11591 if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && (size_and_type.second & (1 << 8)) != 0)
11592 {
11593 auto last_token = get_token_string();
11594 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11595 exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11596 }
11597
11598 string_t key;
11599 if (size_and_type.first != string_t::npos)
11600 {
11601 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11602 {
11603 return false;
11604 }
11605
11606 if (size_and_type.second != 0)
11607 {
11608 for (std::size_t i = 0; i < size_and_type.first; ++i)
11609 {
11610 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11611 {
11612 return false;
11613 }
11614 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11615 {
11616 return false;
11617 }
11618 key.clear();
11619 }
11620 }
11621 else
11622 {
11623 for (std::size_t i = 0; i < size_and_type.first; ++i)
11624 {
11625 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11626 {
11627 return false;
11628 }
11629 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11630 {
11631 return false;
11632 }
11633 key.clear();
11634 }
11635 }
11636 }
11637 else
11638 {
11639 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11640 {
11641 return false;
11642 }
11643
11644 while (current != '}')
11645 {
11646 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11647 {
11648 return false;
11649 }
11650 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11651 {
11652 return false;
11653 }
11654 get_ignore_noop();
11655 key.clear();
11656 }
11657 }
11658
11659 return sax->end_object();
11660 }
11661
11662 // Note, no reader for UBJSON binary types is implemented because they do
11663 // not exist
11664
11666 {
11667 // get size of following number string
11668 std::size_t size{};
11669 bool no_ndarray = true;
11670 auto res = get_ubjson_size_value(size, no_ndarray);
11671 if (JSON_HEDLEY_UNLIKELY(!res))
11672 {
11673 return res;
11674 }
11675
11676 // get number string
11677 std::vector<char> number_vector;
11678 for (std::size_t i = 0; i < size; ++i)
11679 {
11680 get();
11681 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11682 {
11683 return false;
11684 }
11685 number_vector.push_back(static_cast<char>(current));
11686 }
11687
11688 // parse number string
11689 using ia_type = decltype(detail::input_adapter(number_vector));
11690 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11691 const auto result_number = number_lexer.scan();
11692 const auto number_string = number_lexer.get_token_string();
11693 const auto result_remainder = number_lexer.scan();
11694
11695 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11696
11697 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11698 {
11699 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11700 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11701 }
11702
11703 switch (result_number)
11704 {
11705 case token_type::value_integer:
11706 return sax->number_integer(number_lexer.get_number_integer());
11707 case token_type::value_unsigned:
11708 return sax->number_unsigned(number_lexer.get_number_unsigned());
11709 case token_type::value_float:
11710 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11711 case token_type::uninitialized:
11712 case token_type::literal_true:
11713 case token_type::literal_false:
11714 case token_type::literal_null:
11715 case token_type::value_string:
11716 case token_type::begin_array:
11717 case token_type::begin_object:
11718 case token_type::end_array:
11719 case token_type::end_object:
11720 case token_type::name_separator:
11721 case token_type::value_separator:
11722 case token_type::parse_error:
11723 case token_type::end_of_input:
11724 case token_type::literal_or_value:
11725 default:
11726 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11727 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11728 }
11729 }
11730
11732 // Utility functions //
11734
11745 {
11746 ++chars_read;
11747 return current = ia.get_character();
11748 }
11749
11754 {
11755 do
11756 {
11757 get();
11758 }
11759 while (current == 'N');
11760
11761 return current;
11762 }
11763
11764 /*
11765 @brief read a number from the input
11766
11767 @tparam NumberType the type of the number
11768 @param[in] format the current format (for diagnostics)
11769 @param[out] result number of type @a NumberType
11770
11771 @return whether conversion completed
11772
11773 @note This function needs to respect the system's endianness, because
11774 bytes in CBOR, MessagePack, and UBJSON are stored in network order
11775 (big endian) and therefore need reordering on little endian systems.
11776 On the other hand, BSON and BJData use little endian and should reorder
11777 on big endian systems.
11778 */
11779 template<typename NumberType, bool InputIsLittleEndian = false>
11780 bool get_number(const input_format_t format, NumberType& result)
11781 {
11782 // step 1: read input into array with system's byte order
11783 std::array<std::uint8_t, sizeof(NumberType)> vec{};
11784 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11785 {
11786 get();
11787 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11788 {
11789 return false;
11790 }
11791
11792 // reverse byte order prior to conversion if necessary
11793 if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11794 {
11795 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11796 }
11797 else
11798 {
11799 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11800 }
11801 }
11802
11803 // step 2: convert array into number of type T and return
11804 std::memcpy(&result, vec.data(), sizeof(NumberType));
11805 return true;
11806 }
11807
11822 template<typename NumberType>
11823 bool get_string(const input_format_t format,
11824 const NumberType len,
11825 string_t& result)
11826 {
11827 bool success = true;
11828 for (NumberType i = 0; i < len; i++)
11829 {
11830 get();
11831 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11832 {
11833 success = false;
11834 break;
11835 }
11836 result.push_back(static_cast<typename string_t::value_type>(current));
11837 }
11838 return success;
11839 }
11840
11855 template<typename NumberType>
11856 bool get_binary(const input_format_t format,
11857 const NumberType len,
11858 binary_t& result)
11859 {
11860 bool success = true;
11861 for (NumberType i = 0; i < len; i++)
11862 {
11863 get();
11864 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11865 {
11866 success = false;
11867 break;
11868 }
11869 result.push_back(static_cast<std::uint8_t>(current));
11870 }
11871 return success;
11872 }
11873
11880 bool unexpect_eof(const input_format_t format, const char* context) const
11881 {
11882 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11883 {
11884 return sax->parse_error(chars_read, "<end of file>",
11885 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11886 }
11887 return true;
11888 }
11889
11893 std::string get_token_string() const
11894 {
11895 std::array<char, 3> cr{{}};
11896 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11897 return std::string{cr.data()};
11898 }
11899
11906 std::string exception_message(const input_format_t format,
11907 const std::string& detail,
11908 const std::string& context) const
11909 {
11910 std::string error_msg = "syntax error while parsing ";
11911
11912 switch (format)
11913 {
11914 case input_format_t::cbor:
11915 error_msg += "CBOR";
11916 break;
11917
11918 case input_format_t::msgpack:
11919 error_msg += "MessagePack";
11920 break;
11921
11922 case input_format_t::ubjson:
11923 error_msg += "UBJSON";
11924 break;
11925
11926 case input_format_t::bson:
11927 error_msg += "BSON";
11928 break;
11929
11930 case input_format_t::bjdata:
11931 error_msg += "BJData";
11932 break;
11933
11934 case input_format_t::json: // LCOV_EXCL_LINE
11935 default: // LCOV_EXCL_LINE
11936 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
11937 }
11938
11939 return concat(error_msg, ' ', context, ": ", detail);
11940 }
11941
11942 private:
11944 InputAdapterType ia;
11945
11947 char_int_type current = std::char_traits<char_type>::eof();
11948
11950 std::size_t chars_read = 0;
11951
11953 const bool is_little_endian = little_endianness();
11954
11957
11959 json_sax_t* sax = nullptr;
11960};
11961
11962} // namespace detail
11964
11965// #include <nlohmann/detail/input/input_adapters.hpp>
11966
11967// #include <nlohmann/detail/input/lexer.hpp>
11968
11969// #include <nlohmann/detail/input/parser.hpp>
11970// __ _____ _____ _____
11971// __| | __| | | | JSON for Modern C++
11972// | | |__ | | | | | | version 3.11.1
11973// |_____|_____|_____|_|___| https://github.com/nlohmann/json
11974//
11975// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
11976// SPDX-License-Identifier: MIT
11977
11978
11979
11980#include <cmath> // isfinite
11981#include <cstdint> // uint8_t
11982#include <functional> // function
11983#include <string> // string
11984#include <utility> // move
11985#include <vector> // vector
11986
11987// #include <nlohmann/detail/exceptions.hpp>
11988
11989// #include <nlohmann/detail/input/input_adapters.hpp>
11990
11991// #include <nlohmann/detail/input/json_sax.hpp>
11992
11993// #include <nlohmann/detail/input/lexer.hpp>
11994
11995// #include <nlohmann/detail/macro_scope.hpp>
11996
11997// #include <nlohmann/detail/meta/is_sax.hpp>
11998
11999// #include <nlohmann/detail/string_concat.hpp>
12000
12001// #include <nlohmann/detail/value_t.hpp>
12002
12003
12005namespace detail
12006{
12008// parser //
12010
12011enum class parse_event_t : std::uint8_t
12012{
12016 object_end,
12020 array_end,
12022 key,
12024 value
12025};
12026
12027template<typename BasicJsonType>
12029 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12030
12036template<typename BasicJsonType, typename InputAdapterType>
12038{
12039 using number_integer_t = typename BasicJsonType::number_integer_t;
12040 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12041 using number_float_t = typename BasicJsonType::number_float_t;
12042 using string_t = typename BasicJsonType::string_t;
12045
12046 public:
12048 explicit parser(InputAdapterType&& adapter,
12049 const parser_callback_t<BasicJsonType> cb = nullptr,
12050 const bool allow_exceptions_ = true,
12051 const bool skip_comments = false)
12052 : callback(cb)
12053 , m_lexer(std::move(adapter), skip_comments)
12054 , allow_exceptions(allow_exceptions_)
12055 {
12056 // read first token
12057 get_token();
12058 }
12059
12070 void parse(const bool strict, BasicJsonType& result)
12071 {
12072 if (callback)
12073 {
12074 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
12075 sax_parse_internal(&sdp);
12076
12077 // in strict mode, input must be completely read
12078 if (strict && (get_token() != token_type::end_of_input))
12079 {
12080 sdp.parse_error(m_lexer.get_position(),
12081 m_lexer.get_token_string(),
12082 parse_error::create(101, m_lexer.get_position(),
12083 exception_message(token_type::end_of_input, "value"), nullptr));
12084 }
12085
12086 // in case of an error, return discarded value
12087 if (sdp.is_errored())
12088 {
12089 result = value_t::discarded;
12090 return;
12091 }
12092
12093 // set top-level value to null if it was discarded by the callback
12094 // function
12095 if (result.is_discarded())
12096 {
12097 result = nullptr;
12098 }
12099 }
12100 else
12101 {
12102 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
12103 sax_parse_internal(&sdp);
12104
12105 // in strict mode, input must be completely read
12106 if (strict && (get_token() != token_type::end_of_input))
12107 {
12108 sdp.parse_error(m_lexer.get_position(),
12109 m_lexer.get_token_string(),
12110 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12111 }
12112
12113 // in case of an error, return discarded value
12114 if (sdp.is_errored())
12115 {
12116 result = value_t::discarded;
12117 return;
12118 }
12119 }
12120
12121 result.assert_invariant();
12122 }
12123
12130 bool accept(const bool strict = true)
12131 {
12133 return sax_parse(&sax_acceptor, strict);
12134 }
12135
12136 template<typename SAX>
12138 bool sax_parse(SAX* sax, const bool strict = true)
12139 {
12141 const bool result = sax_parse_internal(sax);
12142
12143 // strict mode: next byte must be EOF
12144 if (result && strict && (get_token() != token_type::end_of_input))
12145 {
12146 return sax->parse_error(m_lexer.get_position(),
12147 m_lexer.get_token_string(),
12148 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12149 }
12150
12151 return result;
12152 }
12153
12154 private:
12155 template<typename SAX>
12157 bool sax_parse_internal(SAX* sax)
12158 {
12159 // stack to remember the hierarchy of structured values we are parsing
12160 // true = array; false = object
12161 std::vector<bool> states;
12162 // value to avoid a goto (see comment where set to true)
12163 bool skip_to_state_evaluation = false;
12164
12165 while (true)
12166 {
12167 if (!skip_to_state_evaluation)
12168 {
12169 // invariant: get_token() was called before each iteration
12170 switch (last_token)
12171 {
12172 case token_type::begin_object:
12173 {
12174 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
12175 {
12176 return false;
12177 }
12178
12179 // closing } -> we are done
12180 if (get_token() == token_type::end_object)
12181 {
12182 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12183 {
12184 return false;
12185 }
12186 break;
12187 }
12188
12189 // parse key
12190 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
12191 {
12192 return sax->parse_error(m_lexer.get_position(),
12193 m_lexer.get_token_string(),
12194 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12195 }
12196 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12197 {
12198 return false;
12199 }
12200
12201 // parse separator (:)
12202 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12203 {
12204 return sax->parse_error(m_lexer.get_position(),
12205 m_lexer.get_token_string(),
12206 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12207 }
12208
12209 // remember we are now inside an object
12210 states.push_back(false);
12211
12212 // parse values
12213 get_token();
12214 continue;
12215 }
12216
12217 case token_type::begin_array:
12218 {
12219 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
12220 {
12221 return false;
12222 }
12223
12224 // closing ] -> we are done
12225 if (get_token() == token_type::end_array)
12226 {
12227 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12228 {
12229 return false;
12230 }
12231 break;
12232 }
12233
12234 // remember we are now inside an array
12235 states.push_back(true);
12236
12237 // parse values (no need to call get_token)
12238 continue;
12239 }
12240
12241 case token_type::value_float:
12242 {
12243 const auto res = m_lexer.get_number_float();
12244
12245 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
12246 {
12247 return sax->parse_error(m_lexer.get_position(),
12248 m_lexer.get_token_string(),
12249 out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
12250 }
12251
12252 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
12253 {
12254 return false;
12255 }
12256
12257 break;
12258 }
12259
12260 case token_type::literal_false:
12261 {
12262 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
12263 {
12264 return false;
12265 }
12266 break;
12267 }
12268
12269 case token_type::literal_null:
12270 {
12271 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
12272 {
12273 return false;
12274 }
12275 break;
12276 }
12277
12278 case token_type::literal_true:
12279 {
12280 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
12281 {
12282 return false;
12283 }
12284 break;
12285 }
12286
12287 case token_type::value_integer:
12288 {
12289 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
12290 {
12291 return false;
12292 }
12293 break;
12294 }
12295
12296 case token_type::value_string:
12297 {
12298 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
12299 {
12300 return false;
12301 }
12302 break;
12303 }
12304
12305 case token_type::value_unsigned:
12306 {
12307 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12308 {
12309 return false;
12310 }
12311 break;
12312 }
12313
12314 case token_type::parse_error:
12315 {
12316 // using "uninitialized" to avoid "expected" message
12317 return sax->parse_error(m_lexer.get_position(),
12318 m_lexer.get_token_string(),
12319 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12320 }
12321
12322 case token_type::uninitialized:
12323 case token_type::end_array:
12324 case token_type::end_object:
12325 case token_type::name_separator:
12326 case token_type::value_separator:
12327 case token_type::end_of_input:
12328 case token_type::literal_or_value:
12329 default: // the last token was unexpected
12330 {
12331 return sax->parse_error(m_lexer.get_position(),
12332 m_lexer.get_token_string(),
12333 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12334 }
12335 }
12336 }
12337 else
12338 {
12339 skip_to_state_evaluation = false;
12340 }
12341
12342 // we reached this line after we successfully parsed a value
12343 if (states.empty())
12344 {
12345 // empty stack: we reached the end of the hierarchy: done
12346 return true;
12347 }
12348
12349 if (states.back()) // array
12350 {
12351 // comma -> next value
12352 if (get_token() == token_type::value_separator)
12353 {
12354 // parse a new value
12355 get_token();
12356 continue;
12357 }
12358
12359 // closing ]
12360 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12361 {
12362 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12363 {
12364 return false;
12365 }
12366
12367 // We are done with this array. Before we can parse a
12368 // new value, we need to evaluate the new state first.
12369 // By setting skip_to_state_evaluation to false, we
12370 // are effectively jumping to the beginning of this if.
12371 JSON_ASSERT(!states.empty());
12372 states.pop_back();
12373 skip_to_state_evaluation = true;
12374 continue;
12375 }
12376
12377 return sax->parse_error(m_lexer.get_position(),
12378 m_lexer.get_token_string(),
12379 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12380 }
12381
12382 // states.back() is false -> object
12383
12384 // comma -> next value
12385 if (get_token() == token_type::value_separator)
12386 {
12387 // parse key
12388 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
12389 {
12390 return sax->parse_error(m_lexer.get_position(),
12391 m_lexer.get_token_string(),
12392 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12393 }
12394
12395 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12396 {
12397 return false;
12398 }
12399
12400 // parse separator (:)
12401 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12402 {
12403 return sax->parse_error(m_lexer.get_position(),
12404 m_lexer.get_token_string(),
12405 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12406 }
12407
12408 // parse values
12409 get_token();
12410 continue;
12411 }
12412
12413 // closing }
12414 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12415 {
12416 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12417 {
12418 return false;
12419 }
12420
12421 // We are done with this object. Before we can parse a
12422 // new value, we need to evaluate the new state first.
12423 // By setting skip_to_state_evaluation to false, we
12424 // are effectively jumping to the beginning of this if.
12425 JSON_ASSERT(!states.empty());
12426 states.pop_back();
12427 skip_to_state_evaluation = true;
12428 continue;
12429 }
12430
12431 return sax->parse_error(m_lexer.get_position(),
12432 m_lexer.get_token_string(),
12433 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12434 }
12435 }
12436
12439 {
12440 return last_token = m_lexer.scan();
12441 }
12442
12443 std::string exception_message(const token_type expected, const std::string& context)
12444 {
12445 std::string error_msg = "syntax error ";
12446
12447 if (!context.empty())
12448 {
12449 error_msg += concat("while parsing ", context, ' ');
12450 }
12451
12452 error_msg += "- ";
12453
12454 if (last_token == token_type::parse_error)
12455 {
12456 error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12457 m_lexer.get_token_string(), '\'');
12458 }
12459 else
12460 {
12461 error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12462 }
12463
12464 if (expected != token_type::uninitialized)
12465 {
12466 error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12467 }
12468
12469 return error_msg;
12470 }
12471
12472 private:
12474 const parser_callback_t<BasicJsonType> callback = nullptr;
12476 token_type last_token = token_type::uninitialized;
12480 const bool allow_exceptions = true;
12481};
12482
12483} // namespace detail
12485
12486// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12487// __ _____ _____ _____
12488// __| | __| | | | JSON for Modern C++
12489// | | |__ | | | | | | version 3.11.1
12490// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12491//
12492// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12493// SPDX-License-Identifier: MIT
12494
12495
12496
12497// #include <nlohmann/detail/abi_macros.hpp>
12498
12499// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12500// __ _____ _____ _____
12501// __| | __| | | | JSON for Modern C++
12502// | | |__ | | | | | | version 3.11.1
12503// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12504//
12505// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12506// SPDX-License-Identifier: MIT
12507
12508
12509
12510#include <cstddef> // ptrdiff_t
12511#include <limits> // numeric_limits
12512
12513// #include <nlohmann/detail/macro_scope.hpp>
12514
12515
12517namespace detail
12518{
12519
12520/*
12521@brief an iterator for primitive JSON types
12522
12523This class models an iterator for primitive JSON types (boolean, number,
12524string). It's only purpose is to allow the iterator/const_iterator classes
12525to "iterate" over primitive values. Internally, the iterator is modeled by
12526a `difference_type` variable. Value begin_value (`0`) models the begin,
12527end_value (`1`) models past the end.
12528*/
12530{
12531 private:
12532 using difference_type = std::ptrdiff_t;
12533 static constexpr difference_type begin_value = 0;
12534 static constexpr difference_type end_value = begin_value + 1;
12535
12538 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12539
12540 public:
12541 constexpr difference_type get_value() const noexcept
12542 {
12543 return m_it;
12544 }
12545
12547 void set_begin() noexcept
12548 {
12549 m_it = begin_value;
12550 }
12551
12553 void set_end() noexcept
12554 {
12555 m_it = end_value;
12556 }
12557
12559 constexpr bool is_begin() const noexcept
12560 {
12561 return m_it == begin_value;
12562 }
12563
12565 constexpr bool is_end() const noexcept
12566 {
12567 return m_it == end_value;
12568 }
12569
12570 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12571 {
12572 return lhs.m_it == rhs.m_it;
12573 }
12574
12575 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12576 {
12577 return lhs.m_it < rhs.m_it;
12578 }
12579
12581 {
12582 auto result = *this;
12583 result += n;
12584 return result;
12585 }
12586
12588 {
12589 return lhs.m_it - rhs.m_it;
12590 }
12591
12593 {
12594 ++m_it;
12595 return *this;
12596 }
12597
12598 primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
12599 {
12600 auto result = *this;
12601 ++m_it;
12602 return result;
12603 }
12604
12606 {
12607 --m_it;
12608 return *this;
12609 }
12610
12611 primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
12612 {
12613 auto result = *this;
12614 --m_it;
12615 return result;
12616 }
12617
12619 {
12620 m_it += n;
12621 return *this;
12622 }
12623
12625 {
12626 m_it -= n;
12627 return *this;
12628 }
12629};
12630
12631} // namespace detail
12633
12634
12636namespace detail
12637{
12638
12645template<typename BasicJsonType> struct internal_iterator
12646{
12648 typename BasicJsonType::object_t::iterator object_iterator {};
12650 typename BasicJsonType::array_t::iterator array_iterator {};
12652 primitive_iterator_t primitive_iterator {};
12653};
12654
12655} // namespace detail
12657
12658// #include <nlohmann/detail/iterators/iter_impl.hpp>
12659// __ _____ _____ _____
12660// __| | __| | | | JSON for Modern C++
12661// | | |__ | | | | | | version 3.11.1
12662// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12663//
12664// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12665// SPDX-License-Identifier: MIT
12666
12667
12668
12669#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12670#include <type_traits> // conditional, is_const, remove_const
12671
12672// #include <nlohmann/detail/exceptions.hpp>
12673
12674// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12675
12676// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12677
12678// #include <nlohmann/detail/macro_scope.hpp>
12679
12680// #include <nlohmann/detail/meta/cpp_future.hpp>
12681
12682// #include <nlohmann/detail/meta/type_traits.hpp>
12683
12684// #include <nlohmann/detail/value_t.hpp>
12685
12686
12688namespace detail
12689{
12690
12691// forward declare, to be able to friend it later on
12692template<typename IteratorType> class iteration_proxy;
12693template<typename IteratorType> class iteration_proxy_value;
12694
12711template<typename BasicJsonType>
12712class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12713{
12715 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12721
12722 using object_t = typename BasicJsonType::object_t;
12723 using array_t = typename BasicJsonType::array_t;
12724 // make sure BasicJsonType is basic_json or const basic_json
12726 "iter_impl only accepts (const) basic_json");
12727 // superficial check for the LegacyBidirectionalIterator named requirement
12728 static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12729 && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12730 "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12731
12732 public:
12738 using iterator_category = std::bidirectional_iterator_tag;
12739
12741 using value_type = typename BasicJsonType::value_type;
12743 using difference_type = typename BasicJsonType::difference_type;
12745 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12746 typename BasicJsonType::const_pointer,
12747 typename BasicJsonType::pointer>::type;
12750 typename std::conditional<std::is_const<BasicJsonType>::value,
12751 typename BasicJsonType::const_reference,
12752 typename BasicJsonType::reference>::type;
12753
12754 iter_impl() = default;
12755 ~iter_impl() = default;
12756 iter_impl(iter_impl&&) noexcept = default;
12757 iter_impl& operator=(iter_impl&&) noexcept = default;
12758
12765 explicit iter_impl(pointer object) noexcept : m_object(object)
12766 {
12767 JSON_ASSERT(m_object != nullptr);
12768
12769 switch (m_object->m_type)
12770 {
12771 case value_t::object:
12772 {
12773 m_it.object_iterator = typename object_t::iterator();
12774 break;
12775 }
12776
12777 case value_t::array:
12778 {
12779 m_it.array_iterator = typename array_t::iterator();
12780 break;
12781 }
12782
12783 case value_t::null:
12784 case value_t::string:
12785 case value_t::boolean:
12786 case value_t::number_integer:
12787 case value_t::number_unsigned:
12788 case value_t::number_float:
12789 case value_t::binary:
12790 case value_t::discarded:
12791 default:
12792 {
12793 m_it.primitive_iterator = primitive_iterator_t();
12794 break;
12795 }
12796 }
12797 }
12798
12816 : m_object(other.m_object), m_it(other.m_it)
12817 {}
12818
12826 {
12827 if (&other != this)
12828 {
12829 m_object = other.m_object;
12830 m_it = other.m_it;
12831 }
12832 return *this;
12833 }
12834
12840 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
12841 : m_object(other.m_object), m_it(other.m_it)
12842 {}
12843
12850 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12851 {
12852 m_object = other.m_object;
12853 m_it = other.m_it;
12854 return *this;
12855 }
12856
12862 void set_begin() noexcept
12863 {
12864 JSON_ASSERT(m_object != nullptr);
12865
12866 switch (m_object->m_type)
12867 {
12868 case value_t::object:
12869 {
12870 m_it.object_iterator = m_object->m_value.object->begin();
12871 break;
12872 }
12873
12874 case value_t::array:
12875 {
12876 m_it.array_iterator = m_object->m_value.array->begin();
12877 break;
12878 }
12879
12880 case value_t::null:
12881 {
12882 // set to end so begin()==end() is true: null is empty
12883 m_it.primitive_iterator.set_end();
12884 break;
12885 }
12886
12887 case value_t::string:
12888 case value_t::boolean:
12889 case value_t::number_integer:
12890 case value_t::number_unsigned:
12891 case value_t::number_float:
12892 case value_t::binary:
12893 case value_t::discarded:
12894 default:
12895 {
12896 m_it.primitive_iterator.set_begin();
12897 break;
12898 }
12899 }
12900 }
12901
12906 void set_end() noexcept
12907 {
12908 JSON_ASSERT(m_object != nullptr);
12909
12910 switch (m_object->m_type)
12911 {
12912 case value_t::object:
12913 {
12914 m_it.object_iterator = m_object->m_value.object->end();
12915 break;
12916 }
12917
12918 case value_t::array:
12919 {
12920 m_it.array_iterator = m_object->m_value.array->end();
12921 break;
12922 }
12923
12924 case value_t::null:
12925 case value_t::string:
12926 case value_t::boolean:
12927 case value_t::number_integer:
12928 case value_t::number_unsigned:
12929 case value_t::number_float:
12930 case value_t::binary:
12931 case value_t::discarded:
12932 default:
12933 {
12934 m_it.primitive_iterator.set_end();
12935 break;
12936 }
12937 }
12938 }
12939
12940 public:
12946 {
12947 JSON_ASSERT(m_object != nullptr);
12948
12949 switch (m_object->m_type)
12950 {
12951 case value_t::object:
12952 {
12953 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12954 return m_it.object_iterator->second;
12955 }
12956
12957 case value_t::array:
12958 {
12959 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12960 return *m_it.array_iterator;
12961 }
12962
12963 case value_t::null:
12964 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12965
12966 case value_t::string:
12967 case value_t::boolean:
12968 case value_t::number_integer:
12969 case value_t::number_unsigned:
12970 case value_t::number_float:
12971 case value_t::binary:
12972 case value_t::discarded:
12973 default:
12974 {
12975 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
12976 {
12977 return *m_object;
12978 }
12979
12980 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12981 }
12982 }
12983 }
12984
12990 {
12991 JSON_ASSERT(m_object != nullptr);
12992
12993 switch (m_object->m_type)
12994 {
12995 case value_t::object:
12996 {
12997 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12998 return &(m_it.object_iterator->second);
12999 }
13000
13001 case value_t::array:
13002 {
13003 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
13004 return &*m_it.array_iterator;
13005 }
13006
13007 case value_t::null:
13008 case value_t::string:
13009 case value_t::boolean:
13010 case value_t::number_integer:
13011 case value_t::number_unsigned:
13012 case value_t::number_float:
13013 case value_t::binary:
13014 case value_t::discarded:
13015 default:
13016 {
13017 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13018 {
13019 return m_object;
13020 }
13021
13022 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13023 }
13024 }
13025 }
13026
13031 iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13032 {
13033 auto result = *this;
13034 ++(*this);
13035 return result;
13036 }
13037
13043 {
13044 JSON_ASSERT(m_object != nullptr);
13045
13046 switch (m_object->m_type)
13047 {
13048 case value_t::object:
13049 {
13050 std::advance(m_it.object_iterator, 1);
13051 break;
13052 }
13053
13054 case value_t::array:
13055 {
13056 std::advance(m_it.array_iterator, 1);
13057 break;
13058 }
13059
13060 case value_t::null:
13061 case value_t::string:
13062 case value_t::boolean:
13063 case value_t::number_integer:
13064 case value_t::number_unsigned:
13065 case value_t::number_float:
13066 case value_t::binary:
13067 case value_t::discarded:
13068 default:
13069 {
13070 ++m_it.primitive_iterator;
13071 break;
13072 }
13073 }
13074
13075 return *this;
13076 }
13077
13082 iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13083 {
13084 auto result = *this;
13085 --(*this);
13086 return result;
13087 }
13088
13094 {
13095 JSON_ASSERT(m_object != nullptr);
13096
13097 switch (m_object->m_type)
13098 {
13099 case value_t::object:
13100 {
13101 std::advance(m_it.object_iterator, -1);
13102 break;
13103 }
13104
13105 case value_t::array:
13106 {
13107 std::advance(m_it.array_iterator, -1);
13108 break;
13109 }
13110
13111 case value_t::null:
13112 case value_t::string:
13113 case value_t::boolean:
13114 case value_t::number_integer:
13115 case value_t::number_unsigned:
13116 case value_t::number_float:
13117 case value_t::binary:
13118 case value_t::discarded:
13119 default:
13120 {
13121 --m_it.primitive_iterator;
13122 break;
13123 }
13124 }
13125
13126 return *this;
13127 }
13128
13133 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
13134 bool operator==(const IterImpl& other) const
13135 {
13136 // if objects are not the same, the comparison is undefined
13137 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13138 {
13139 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13140 }
13141
13142 JSON_ASSERT(m_object != nullptr);
13143
13144 switch (m_object->m_type)
13145 {
13146 case value_t::object:
13147 return (m_it.object_iterator == other.m_it.object_iterator);
13148
13149 case value_t::array:
13150 return (m_it.array_iterator == other.m_it.array_iterator);
13151
13152 case value_t::null:
13153 case value_t::string:
13154 case value_t::boolean:
13155 case value_t::number_integer:
13156 case value_t::number_unsigned:
13157 case value_t::number_float:
13158 case value_t::binary:
13159 case value_t::discarded:
13160 default:
13161 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
13162 }
13163 }
13164
13169 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
13170 bool operator!=(const IterImpl& other) const
13171 {
13172 return !operator==(other);
13173 }
13174
13179 bool operator<(const iter_impl& other) const
13180 {
13181 // if objects are not the same, the comparison is undefined
13182 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13183 {
13184 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13185 }
13186
13187 JSON_ASSERT(m_object != nullptr);
13188
13189 switch (m_object->m_type)
13190 {
13191 case value_t::object:
13192 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
13193
13194 case value_t::array:
13195 return (m_it.array_iterator < other.m_it.array_iterator);
13196
13197 case value_t::null:
13198 case value_t::string:
13199 case value_t::boolean:
13200 case value_t::number_integer:
13201 case value_t::number_unsigned:
13202 case value_t::number_float:
13203 case value_t::binary:
13204 case value_t::discarded:
13205 default:
13206 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
13207 }
13208 }
13209
13214 bool operator<=(const iter_impl& other) const
13215 {
13216 return !other.operator < (*this);
13217 }
13218
13223 bool operator>(const iter_impl& other) const
13224 {
13225 return !operator<=(other);
13226 }
13227
13232 bool operator>=(const iter_impl& other) const
13233 {
13234 return !operator<(other);
13235 }
13236
13242 {
13243 JSON_ASSERT(m_object != nullptr);
13244
13245 switch (m_object->m_type)
13246 {
13247 case value_t::object:
13248 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13249
13250 case value_t::array:
13251 {
13252 std::advance(m_it.array_iterator, i);
13253 break;
13254 }
13255
13256 case value_t::null:
13257 case value_t::string:
13258 case value_t::boolean:
13259 case value_t::number_integer:
13260 case value_t::number_unsigned:
13261 case value_t::number_float:
13262 case value_t::binary:
13263 case value_t::discarded:
13264 default:
13265 {
13266 m_it.primitive_iterator += i;
13267 break;
13268 }
13269 }
13270
13271 return *this;
13272 }
13273
13279 {
13280 return operator+=(-i);
13281 }
13282
13288 {
13289 auto result = *this;
13290 result += i;
13291 return result;
13292 }
13293
13299 {
13300 auto result = it;
13301 result += i;
13302 return result;
13303 }
13304
13310 {
13311 auto result = *this;
13312 result -= i;
13313 return result;
13314 }
13315
13321 {
13322 JSON_ASSERT(m_object != nullptr);
13323
13324 switch (m_object->m_type)
13325 {
13326 case value_t::object:
13327 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13328
13329 case value_t::array:
13330 return m_it.array_iterator - other.m_it.array_iterator;
13331
13332 case value_t::null:
13333 case value_t::string:
13334 case value_t::boolean:
13335 case value_t::number_integer:
13336 case value_t::number_unsigned:
13337 case value_t::number_float:
13338 case value_t::binary:
13339 case value_t::discarded:
13340 default:
13341 return m_it.primitive_iterator - other.m_it.primitive_iterator;
13342 }
13343 }
13344
13350 {
13351 JSON_ASSERT(m_object != nullptr);
13352
13353 switch (m_object->m_type)
13354 {
13355 case value_t::object:
13356 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13357
13358 case value_t::array:
13359 return *std::next(m_it.array_iterator, n);
13360
13361 case value_t::null:
13362 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13363
13364 case value_t::string:
13365 case value_t::boolean:
13366 case value_t::number_integer:
13367 case value_t::number_unsigned:
13368 case value_t::number_float:
13369 case value_t::binary:
13370 case value_t::discarded:
13371 default:
13372 {
13373 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
13374 {
13375 return *m_object;
13376 }
13377
13378 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13379 }
13380 }
13381 }
13382
13387 const typename object_t::key_type& key() const
13388 {
13389 JSON_ASSERT(m_object != nullptr);
13390
13391 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13392 {
13393 return m_it.object_iterator->first;
13394 }
13395
13396 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13397 }
13398
13404 {
13405 return operator*();
13406 }
13407
13410 pointer m_object = nullptr;
13413};
13414
13415} // namespace detail
13417
13418// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13419
13420// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13421// __ _____ _____ _____
13422// __| | __| | | | JSON for Modern C++
13423// | | |__ | | | | | | version 3.11.1
13424// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13425//
13426// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13427// SPDX-License-Identifier: MIT
13428
13429
13430
13431#include <cstddef> // ptrdiff_t
13432#include <iterator> // reverse_iterator
13433#include <utility> // declval
13434
13435// #include <nlohmann/detail/abi_macros.hpp>
13436
13437
13439namespace detail
13440{
13441
13443// reverse_iterator //
13445
13464template<typename Base>
13465class json_reverse_iterator : public std::reverse_iterator<Base>
13466{
13467 public:
13468 using difference_type = std::ptrdiff_t;
13470 using base_iterator = std::reverse_iterator<Base>;
13472 using reference = typename Base::reference;
13473
13475 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13476 : base_iterator(it) {}
13477
13479 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13480
13482 json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13483 {
13484 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13485 }
13486
13489 {
13490 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13491 }
13492
13494 json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13495 {
13496 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13497 }
13498
13501 {
13502 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13503 }
13504
13507 {
13508 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13509 }
13510
13513 {
13514 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13515 }
13516
13519 {
13520 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13521 }
13522
13525 {
13526 return base_iterator(*this) - base_iterator(other);
13527 }
13528
13531 {
13532 return *(this->operator+(n));
13533 }
13534
13536 auto key() const -> decltype(std::declval<Base>().key())
13537 {
13538 auto it = --this->base();
13539 return it.key();
13540 }
13541
13544 {
13545 auto it = --this->base();
13546 return it.operator * ();
13547 }
13548};
13549
13550} // namespace detail
13552
13553// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13554
13555// #include <nlohmann/detail/json_pointer.hpp>
13556// __ _____ _____ _____
13557// __| | __| | | | JSON for Modern C++
13558// | | |__ | | | | | | version 3.11.1
13559// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13560//
13561// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13562// SPDX-License-Identifier: MIT
13563
13564
13565
13566#include <algorithm> // all_of
13567#include <cctype> // isdigit
13568#include <cerrno> // errno, ERANGE
13569#include <cstdlib> // strtoull
13570#ifndef JSON_NO_IO
13571 #include <iosfwd> // ostream
13572#endif // JSON_NO_IO
13573#include <limits> // max
13574#include <numeric> // accumulate
13575#include <string> // string
13576#include <utility> // move
13577#include <vector> // vector
13578
13579// #include <nlohmann/detail/exceptions.hpp>
13580
13581// #include <nlohmann/detail/macro_scope.hpp>
13582
13583// #include <nlohmann/detail/string_concat.hpp>
13584
13585// #include <nlohmann/detail/string_escape.hpp>
13586
13587// #include <nlohmann/detail/value_t.hpp>
13588
13589
13591
13594template<typename RefStringType>
13596{
13597 // allow basic_json to access private members
13599 friend class basic_json;
13600
13601 template<typename>
13602 friend class json_pointer;
13603
13604 template<typename T>
13606 {
13607 using type = T;
13608 };
13609
13612 {
13613 using type = StringType;
13614 };
13615
13616 public:
13617 // for backwards compatibility accept BasicJsonType
13619
13622 explicit json_pointer(const string_t& s = "")
13623 : reference_tokens(split(s))
13624 {}
13625
13629 {
13630 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13631 string_t{},
13632 [](const string_t& a, const string_t& b)
13633 {
13634 return detail::concat(a, '/', detail::escape(b));
13635 });
13636 }
13637
13641 operator string_t() const
13642 {
13643 return to_string();
13644 }
13645
13646#ifndef JSON_NO_IO
13649 friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13650 {
13651 o << ptr.to_string();
13652 return o;
13653 }
13654#endif
13655
13659 {
13660 reference_tokens.insert(reference_tokens.end(),
13661 ptr.reference_tokens.begin(),
13662 ptr.reference_tokens.end());
13663 return *this;
13664 }
13665
13669 {
13670 push_back(std::move(token));
13671 return *this;
13672 }
13673
13676 json_pointer& operator/=(std::size_t array_idx)
13677 {
13678 return *this /= std::to_string(array_idx);
13679 }
13680
13684 const json_pointer& rhs)
13685 {
13686 return json_pointer(lhs) /= rhs;
13687 }
13688
13691 friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13692 {
13693 return json_pointer(lhs) /= std::move(token);
13694 }
13695
13698 friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13699 {
13700 return json_pointer(lhs) /= array_idx;
13701 }
13702
13706 {
13707 if (empty())
13708 {
13709 return *this;
13710 }
13711
13712 json_pointer res = *this;
13713 res.pop_back();
13714 return res;
13715 }
13716
13720 {
13721 if (JSON_HEDLEY_UNLIKELY(empty()))
13722 {
13723 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13724 }
13725
13726 reference_tokens.pop_back();
13727 }
13728
13731 const string_t& back() const
13732 {
13733 if (JSON_HEDLEY_UNLIKELY(empty()))
13734 {
13735 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13736 }
13737
13738 return reference_tokens.back();
13739 }
13740
13743 void push_back(const string_t& token)
13744 {
13745 reference_tokens.push_back(token);
13746 }
13747
13750 void push_back(string_t&& token)
13751 {
13752 reference_tokens.push_back(std::move(token));
13753 }
13754
13757 bool empty() const noexcept
13758 {
13759 return reference_tokens.empty();
13760 }
13761
13762 private:
13773 template<typename BasicJsonType>
13774 static typename BasicJsonType::size_type array_index(const string_t& s)
13775 {
13776 using size_type = typename BasicJsonType::size_type;
13777
13778 // error condition (cf. RFC 6901, Sect. 4)
13779 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13780 {
13781 JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13782 }
13783
13784 // error condition (cf. RFC 6901, Sect. 4)
13785 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13786 {
13787 JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13788 }
13789
13790 const char* p = s.c_str();
13791 char* p_end = nullptr;
13792 errno = 0; // strtoull doesn't reset errno
13793 unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13794 if (p == p_end // invalid input or empty string
13795 || errno == ERANGE // out of range
13796 || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13797 {
13798 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13799 }
13800
13801 // only triggered on special platforms (like 32bit), see also
13802 // https://github.com/nlohmann/json/pull/2203
13803 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13804 {
13805 JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13806 }
13807
13808 return static_cast<size_type>(res);
13809 }
13810
13812 json_pointer top() const
13813 {
13814 if (JSON_HEDLEY_UNLIKELY(empty()))
13815 {
13816 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13817 }
13818
13819 json_pointer result = *this;
13820 result.reference_tokens = {reference_tokens[0]};
13821 return result;
13822 }
13823
13824 private:
13833 template<typename BasicJsonType>
13834 BasicJsonType& get_and_create(BasicJsonType& j) const
13835 {
13836 auto* result = &j;
13837
13838 // in case no reference tokens exist, return a reference to the JSON value
13839 // j which will be overwritten by a primitive value
13840 for (const auto& reference_token : reference_tokens)
13841 {
13842 switch (result->type())
13843 {
13845 {
13846 if (reference_token == "0")
13847 {
13848 // start a new array if reference token is 0
13849 result = &result->operator[](0);
13850 }
13851 else
13852 {
13853 // start a new object otherwise
13854 result = &result->operator[](reference_token);
13855 }
13856 break;
13857 }
13858
13860 {
13861 // create an entry in the object
13862 result = &result->operator[](reference_token);
13863 break;
13864 }
13865
13867 {
13868 // create an entry in the array
13869 result = &result->operator[](array_index<BasicJsonType>(reference_token));
13870 break;
13871 }
13872
13873 /*
13874 The following code is only reached if there exists a reference
13875 token _and_ the current value is primitive. In this case, we have
13876 an error situation, because primitive values may only occur as
13877 single value; that is, with an empty list of reference tokens.
13878 */
13886 default:
13887 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
13888 }
13889 }
13890
13891 return *result;
13892 }
13893
13913 template<typename BasicJsonType>
13914 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
13915 {
13916 for (const auto& reference_token : reference_tokens)
13917 {
13918 // convert null values to arrays or objects before continuing
13919 if (ptr->is_null())
13920 {
13921 // check if reference token is a number
13922 const bool nums =
13923 std::all_of(reference_token.begin(), reference_token.end(),
13924 [](const unsigned char x)
13925 {
13926 return std::isdigit(x);
13927 });
13928
13929 // change value to array for numbers or "-" or to object otherwise
13930 *ptr = (nums || reference_token == "-")
13933 }
13934
13935 switch (ptr->type())
13936 {
13938 {
13939 // use unchecked object access
13940 ptr = &ptr->operator[](reference_token);
13941 break;
13942 }
13943
13945 {
13946 if (reference_token == "-")
13947 {
13948 // explicitly treat "-" as index beyond the end
13949 ptr = &ptr->operator[](ptr->m_value.array->size());
13950 }
13951 else
13952 {
13953 // convert array index to number; unchecked access
13954 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13955 }
13956 break;
13957 }
13958
13967 default:
13968 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13969 }
13970 }
13971
13972 return *ptr;
13973 }
13974
13981 template<typename BasicJsonType>
13982 BasicJsonType& get_checked(BasicJsonType* ptr) const
13983 {
13984 for (const auto& reference_token : reference_tokens)
13985 {
13986 switch (ptr->type())
13987 {
13989 {
13990 // note: at performs range check
13991 ptr = &ptr->at(reference_token);
13992 break;
13993 }
13994
13996 {
13997 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13998 {
13999 // "-" always fails the range check
14001 "array index '-' (", std::to_string(ptr->m_value.array->size()),
14002 ") is out of range"), ptr));
14003 }
14004
14005 // note: at performs range check
14006 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14007 break;
14008 }
14009
14018 default:
14019 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14020 }
14021 }
14022
14023 return *ptr;
14024 }
14025
14039 template<typename BasicJsonType>
14040 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14041 {
14042 for (const auto& reference_token : reference_tokens)
14043 {
14044 switch (ptr->type())
14045 {
14047 {
14048 // use unchecked object access
14049 ptr = &ptr->operator[](reference_token);
14050 break;
14051 }
14052
14054 {
14055 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14056 {
14057 // "-" cannot be used for const access
14058 JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr));
14059 }
14060
14061 // use unchecked array access
14062 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14063 break;
14064 }
14065
14074 default:
14075 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14076 }
14077 }
14078
14079 return *ptr;
14080 }
14081
14088 template<typename BasicJsonType>
14089 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
14090 {
14091 for (const auto& reference_token : reference_tokens)
14092 {
14093 switch (ptr->type())
14094 {
14096 {
14097 // note: at performs range check
14098 ptr = &ptr->at(reference_token);
14099 break;
14100 }
14101
14103 {
14104 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14105 {
14106 // "-" always fails the range check
14108 "array index '-' (", std::to_string(ptr->m_value.array->size()),
14109 ") is out of range"), ptr));
14110 }
14111
14112 // note: at performs range check
14113 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14114 break;
14115 }
14116
14125 default:
14126 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14127 }
14128 }
14129
14130 return *ptr;
14131 }
14132
14137 template<typename BasicJsonType>
14138 bool contains(const BasicJsonType* ptr) const
14139 {
14140 for (const auto& reference_token : reference_tokens)
14141 {
14142 switch (ptr->type())
14143 {
14145 {
14146 if (!ptr->contains(reference_token))
14147 {
14148 // we did not find the key in the object
14149 return false;
14150 }
14151
14152 ptr = &ptr->operator[](reference_token);
14153 break;
14154 }
14155
14157 {
14158 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14159 {
14160 // "-" always fails the range check
14161 return false;
14162 }
14163 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
14164 {
14165 // invalid char
14166 return false;
14167 }
14168 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
14169 {
14170 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
14171 {
14172 // first char should be between '1' and '9'
14173 return false;
14174 }
14175 for (std::size_t i = 1; i < reference_token.size(); i++)
14176 {
14177 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
14178 {
14179 // other char should be between '0' and '9'
14180 return false;
14181 }
14182 }
14183 }
14184
14185 const auto idx = array_index<BasicJsonType>(reference_token);
14186 if (idx >= ptr->size())
14187 {
14188 // index out of range
14189 return false;
14190 }
14191
14192 ptr = &ptr->operator[](idx);
14193 break;
14194 }
14195
14204 default:
14205 {
14206 // we do not expect primitive values if there is still a
14207 // reference token to process
14208 return false;
14209 }
14210 }
14211 }
14212
14213 // no reference token left means we found a primitive value
14214 return true;
14215 }
14216
14226 static std::vector<string_t> split(const string_t& reference_string)
14227 {
14228 std::vector<string_t> result;
14229
14230 // special case: empty reference string -> no reference tokens
14231 if (reference_string.empty())
14232 {
14233 return result;
14234 }
14235
14236 // check if nonempty reference string begins with slash
14237 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
14238 {
14239 JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
14240 }
14241
14242 // extract the reference tokens:
14243 // - slash: position of the last read slash (or end of string)
14244 // - start: position after the previous slash
14245 for (
14246 // search for the first slash after the first character
14247 std::size_t slash = reference_string.find_first_of('/', 1),
14248 // set the beginning of the first reference token
14249 start = 1;
14250 // we can stop if start == 0 (if slash == string_t::npos)
14251 start != 0;
14252 // set the beginning of the next reference token
14253 // (will eventually be 0 if slash == string_t::npos)
14254 start = (slash == string_t::npos) ? 0 : slash + 1,
14255 // find next slash
14256 slash = reference_string.find_first_of('/', start))
14257 {
14258 // use the text between the beginning of the reference token
14259 // (start) and the last slash (slash).
14260 auto reference_token = reference_string.substr(start, slash - start);
14261
14262 // check reference tokens are properly escaped
14263 for (std::size_t pos = reference_token.find_first_of('~');
14264 pos != string_t::npos;
14265 pos = reference_token.find_first_of('~', pos + 1))
14266 {
14267 JSON_ASSERT(reference_token[pos] == '~');
14268
14269 // ~ must be followed by 0 or 1
14270 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
14271 (reference_token[pos + 1] != '0' &&
14272 reference_token[pos + 1] != '1')))
14273 {
14274 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
14275 }
14276 }
14277
14278 // finally, store the reference token
14279 detail::unescape(reference_token);
14280 result.push_back(reference_token);
14281 }
14282
14283 return result;
14284 }
14285
14286 private:
14294 template<typename BasicJsonType>
14295 static void flatten(const string_t& reference_string,
14296 const BasicJsonType& value,
14297 BasicJsonType& result)
14298 {
14299 switch (value.type())
14300 {
14302 {
14303 if (value.m_value.array->empty())
14304 {
14305 // flatten empty array as null
14306 result[reference_string] = nullptr;
14307 }
14308 else
14309 {
14310 // iterate array and use index as reference string
14311 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
14312 {
14313 flatten(detail::concat(reference_string, '/', std::to_string(i)),
14314 value.m_value.array->operator[](i), result);
14315 }
14316 }
14317 break;
14318 }
14319
14321 {
14322 if (value.m_value.object->empty())
14323 {
14324 // flatten empty object as null
14325 result[reference_string] = nullptr;
14326 }
14327 else
14328 {
14329 // iterate object and use keys as reference string
14330 for (const auto& element : *value.m_value.object)
14331 {
14332 flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
14333 }
14334 }
14335 break;
14336 }
14337
14346 default:
14347 {
14348 // add primitive value with its reference string
14349 result[reference_string] = value;
14350 break;
14351 }
14352 }
14353 }
14354
14365 template<typename BasicJsonType>
14366 static BasicJsonType
14367 unflatten(const BasicJsonType& value)
14368 {
14369 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14370 {
14371 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14372 }
14373
14374 BasicJsonType result;
14375
14376 // iterate the JSON object values
14377 for (const auto& element : *value.m_value.object)
14378 {
14379 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14380 {
14381 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14382 }
14383
14384 // assign value to reference pointed to by JSON pointer; Note that if
14385 // the JSON pointer is "" (i.e., points to the whole value), function
14386 // get_and_create returns a reference to result itself. An assignment
14387 // will then create a primitive value.
14388 json_pointer(element.first).get_and_create(result) = element.second;
14389 }
14390
14391 return result;
14392 }
14393
14394 // can't use conversion operator because of ambiguity
14396 {
14398 result.reference_tokens = reference_tokens;
14399 return result;
14400 }
14401
14403 {
14405 result.reference_tokens = std::move(reference_tokens);
14406 return result;
14407 }
14408
14420 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14421 // NOLINTNEXTLINE(readability-redundant-declaration)
14422 friend bool operator==(json_pointer<RefStringTypeLhs> const& lhs,
14423 json_pointer<RefStringTypeRhs> const& rhs) noexcept;
14424
14436 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14437 // NOLINTNEXTLINE(readability-redundant-declaration)
14438 friend bool operator!=(json_pointer<RefStringTypeLhs> const& lhs,
14439 json_pointer<RefStringTypeRhs> const& rhs) noexcept;
14440
14442 std::vector<string_t> reference_tokens;
14443};
14444
14445// functions cannot be defined inside class due to ODR violations
14446template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14448 json_pointer<RefStringTypeRhs> const& rhs) noexcept
14449{
14450 return lhs.reference_tokens == rhs.reference_tokens;
14451}
14452
14453template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14455 json_pointer<RefStringTypeRhs> const& rhs) noexcept
14456{
14457 return !(lhs == rhs);
14458}
14459
14461
14462// #include <nlohmann/detail/json_ref.hpp>
14463// __ _____ _____ _____
14464// __| | __| | | | JSON for Modern C++
14465// | | |__ | | | | | | version 3.11.1
14466// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14467//
14468// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14469// SPDX-License-Identifier: MIT
14470
14471
14472
14473#include <initializer_list>
14474#include <utility>
14475
14476// #include <nlohmann/detail/abi_macros.hpp>
14477
14478// #include <nlohmann/detail/meta/type_traits.hpp>
14479
14480
14482namespace detail
14483{
14484
14485template<typename BasicJsonType>
14487{
14488 public:
14489 using value_type = BasicJsonType;
14490
14492 : owned_value(std::move(value))
14493 {}
14494
14495 json_ref(const value_type& value)
14496 : value_ref(&value)
14497 {}
14498
14499 json_ref(std::initializer_list<json_ref> init)
14500 : owned_value(init)
14501 {}
14502
14503 template <
14504 class... Args,
14505 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14506 json_ref(Args && ... args)
14507 : owned_value(std::forward<Args>(args)...)
14508 {}
14509
14510 // class should be movable only
14511 json_ref(json_ref&&) noexcept = default;
14512 json_ref(const json_ref&) = delete;
14513 json_ref& operator=(const json_ref&) = delete;
14514 json_ref& operator=(json_ref&&) = delete;
14515 ~json_ref() = default;
14516
14517 value_type moved_or_copied() const
14518 {
14519 if (value_ref == nullptr)
14520 {
14521 return std::move(owned_value);
14522 }
14523 return *value_ref;
14524 }
14525
14526 value_type const& operator*() const
14527 {
14528 return value_ref ? *value_ref : owned_value;
14529 }
14530
14531 value_type const* operator->() const
14532 {
14533 return &** this;
14534 }
14535
14536 private:
14537 mutable value_type owned_value = nullptr;
14538 value_type const* value_ref = nullptr;
14539};
14540
14541} // namespace detail
14543
14544// #include <nlohmann/detail/macro_scope.hpp>
14545
14546// #include <nlohmann/detail/string_concat.hpp>
14547
14548// #include <nlohmann/detail/string_escape.hpp>
14549
14550// #include <nlohmann/detail/meta/cpp_future.hpp>
14551
14552// #include <nlohmann/detail/meta/type_traits.hpp>
14553
14554// #include <nlohmann/detail/output/binary_writer.hpp>
14555// __ _____ _____ _____
14556// __| | __| | | | JSON for Modern C++
14557// | | |__ | | | | | | version 3.11.1
14558// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14559//
14560// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14561// SPDX-License-Identifier: MIT
14562
14563
14564
14565#include <algorithm> // reverse
14566#include <array> // array
14567#include <map> // map
14568#include <cmath> // isnan, isinf
14569#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14570#include <cstring> // memcpy
14571#include <limits> // numeric_limits
14572#include <string> // string
14573#include <utility> // move
14574#include <vector> // vector
14575
14576// #include <nlohmann/detail/input/binary_reader.hpp>
14577
14578// #include <nlohmann/detail/macro_scope.hpp>
14579
14580// #include <nlohmann/detail/output/output_adapters.hpp>
14581// __ _____ _____ _____
14582// __| | __| | | | JSON for Modern C++
14583// | | |__ | | | | | | version 3.11.1
14584// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14585//
14586// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14587// SPDX-License-Identifier: MIT
14588
14589
14590
14591#include <algorithm> // copy
14592#include <cstddef> // size_t
14593#include <iterator> // back_inserter
14594#include <memory> // shared_ptr, make_shared
14595#include <string> // basic_string
14596#include <vector> // vector
14597
14598#ifndef JSON_NO_IO
14599 #include <ios> // streamsize
14600 #include <ostream> // basic_ostream
14601#endif // JSON_NO_IO
14602
14603// #include <nlohmann/detail/macro_scope.hpp>
14604
14605
14607namespace detail
14608{
14609
14611template<typename CharType> struct output_adapter_protocol
14612{
14613 virtual void write_character(CharType c) = 0;
14614 virtual void write_characters(const CharType* s, std::size_t length) = 0;
14615 virtual ~output_adapter_protocol() = default;
14616
14621 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
14622};
14623
14625template<typename CharType>
14626using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14627
14629template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14631{
14632 public:
14633 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14634 : v(vec)
14635 {}
14636
14637 void write_character(CharType c) override
14638 {
14639 v.push_back(c);
14640 }
14641
14643 void write_characters(const CharType* s, std::size_t length) override
14644 {
14645 v.insert(v.end(), s, s + length);
14646 }
14647
14648 private:
14649 std::vector<CharType, AllocatorType>& v;
14650};
14651
14652#ifndef JSON_NO_IO
14654template<typename CharType>
14656{
14657 public:
14658 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14659 : stream(s)
14660 {}
14661
14662 void write_character(CharType c) override
14663 {
14664 stream.put(c);
14665 }
14666
14668 void write_characters(const CharType* s, std::size_t length) override
14669 {
14670 stream.write(s, static_cast<std::streamsize>(length));
14671 }
14672
14673 private:
14674 std::basic_ostream<CharType>& stream;
14675};
14676#endif // JSON_NO_IO
14677
14679template<typename CharType, typename StringType = std::basic_string<CharType>>
14681{
14682 public:
14683 explicit output_string_adapter(StringType& s) noexcept
14684 : str(s)
14685 {}
14686
14687 void write_character(CharType c) override
14688 {
14689 str.push_back(c);
14690 }
14691
14693 void write_characters(const CharType* s, std::size_t length) override
14694 {
14695 str.append(s, length);
14696 }
14697
14698 private:
14699 StringType& str;
14700};
14701
14702template<typename CharType, typename StringType = std::basic_string<CharType>>
14704{
14705 public:
14706 template<typename AllocatorType = std::allocator<CharType>>
14707 output_adapter(std::vector<CharType, AllocatorType>& vec)
14708 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
14709
14710#ifndef JSON_NO_IO
14711 output_adapter(std::basic_ostream<CharType>& s)
14712 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
14713#endif // JSON_NO_IO
14714
14715 output_adapter(StringType& s)
14716 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
14717
14719 {
14720 return oa;
14721 }
14722
14723 private:
14725};
14726
14727} // namespace detail
14729
14730// #include <nlohmann/detail/string_concat.hpp>
14731
14732
14734namespace detail
14735{
14736
14738// binary writer //
14740
14744template<typename BasicJsonType, typename CharType>
14746{
14747 using string_t = typename BasicJsonType::string_t;
14748 using binary_t = typename BasicJsonType::binary_t;
14749 using number_float_t = typename BasicJsonType::number_float_t;
14750
14751 public:
14757 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
14758 {
14759 JSON_ASSERT(oa);
14760 }
14761
14766 void write_bson(const BasicJsonType& j)
14767 {
14768 switch (j.type())
14769 {
14770 case value_t::object:
14771 {
14772 write_bson_object(*j.m_value.object);
14773 break;
14774 }
14775
14776 case value_t::null:
14777 case value_t::array:
14778 case value_t::string:
14779 case value_t::boolean:
14780 case value_t::number_integer:
14781 case value_t::number_unsigned:
14782 case value_t::number_float:
14783 case value_t::binary:
14784 case value_t::discarded:
14785 default:
14786 {
14787 JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
14788 }
14789 }
14790 }
14791
14795 void write_cbor(const BasicJsonType& j)
14796 {
14797 switch (j.type())
14798 {
14799 case value_t::null:
14800 {
14801 oa->write_character(to_char_type(0xF6));
14802 break;
14803 }
14804
14805 case value_t::boolean:
14806 {
14807 oa->write_character(j.m_value.boolean
14808 ? to_char_type(0xF5)
14809 : to_char_type(0xF4));
14810 break;
14811 }
14812
14813 case value_t::number_integer:
14814 {
14815 if (j.m_value.number_integer >= 0)
14816 {
14817 // CBOR does not differentiate between positive signed
14818 // integers and unsigned integers. Therefore, we used the
14819 // code from the value_t::number_unsigned case here.
14820 if (j.m_value.number_integer <= 0x17)
14821 {
14822 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14823 }
14824 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14825 {
14826 oa->write_character(to_char_type(0x18));
14827 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14828 }
14829 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
14830 {
14831 oa->write_character(to_char_type(0x19));
14832 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14833 }
14834 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
14835 {
14836 oa->write_character(to_char_type(0x1A));
14837 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14838 }
14839 else
14840 {
14841 oa->write_character(to_char_type(0x1B));
14842 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14843 }
14844 }
14845 else
14846 {
14847 // The conversions below encode the sign in the first
14848 // byte, and the value is converted to a positive number.
14849 const auto positive_number = -1 - j.m_value.number_integer;
14850 if (j.m_value.number_integer >= -24)
14851 {
14852 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
14853 }
14854 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
14855 {
14856 oa->write_character(to_char_type(0x38));
14857 write_number(static_cast<std::uint8_t>(positive_number));
14858 }
14859 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
14860 {
14861 oa->write_character(to_char_type(0x39));
14862 write_number(static_cast<std::uint16_t>(positive_number));
14863 }
14864 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
14865 {
14866 oa->write_character(to_char_type(0x3A));
14867 write_number(static_cast<std::uint32_t>(positive_number));
14868 }
14869 else
14870 {
14871 oa->write_character(to_char_type(0x3B));
14872 write_number(static_cast<std::uint64_t>(positive_number));
14873 }
14874 }
14875 break;
14876 }
14877
14878 case value_t::number_unsigned:
14879 {
14880 if (j.m_value.number_unsigned <= 0x17)
14881 {
14882 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14883 }
14884 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14885 {
14886 oa->write_character(to_char_type(0x18));
14887 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14888 }
14889 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14890 {
14891 oa->write_character(to_char_type(0x19));
14892 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
14893 }
14894 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14895 {
14896 oa->write_character(to_char_type(0x1A));
14897 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
14898 }
14899 else
14900 {
14901 oa->write_character(to_char_type(0x1B));
14902 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
14903 }
14904 break;
14905 }
14906
14907 case value_t::number_float:
14908 {
14909 if (std::isnan(j.m_value.number_float))
14910 {
14911 // NaN is 0xf97e00 in CBOR
14912 oa->write_character(to_char_type(0xF9));
14913 oa->write_character(to_char_type(0x7E));
14914 oa->write_character(to_char_type(0x00));
14915 }
14916 else if (std::isinf(j.m_value.number_float))
14917 {
14918 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
14919 oa->write_character(to_char_type(0xf9));
14920 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
14921 oa->write_character(to_char_type(0x00));
14922 }
14923 else
14924 {
14925 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
14926 }
14927 break;
14928 }
14929
14930 case value_t::string:
14931 {
14932 // step 1: write control byte and the string length
14933 const auto N = j.m_value.string->size();
14934 if (N <= 0x17)
14935 {
14936 write_number(static_cast<std::uint8_t>(0x60 + N));
14937 }
14938 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14939 {
14940 oa->write_character(to_char_type(0x78));
14941 write_number(static_cast<std::uint8_t>(N));
14942 }
14943 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14944 {
14945 oa->write_character(to_char_type(0x79));
14946 write_number(static_cast<std::uint16_t>(N));
14947 }
14948 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14949 {
14950 oa->write_character(to_char_type(0x7A));
14951 write_number(static_cast<std::uint32_t>(N));
14952 }
14953 // LCOV_EXCL_START
14954 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14955 {
14956 oa->write_character(to_char_type(0x7B));
14957 write_number(static_cast<std::uint64_t>(N));
14958 }
14959 // LCOV_EXCL_STOP
14960
14961 // step 2: write the string
14962 oa->write_characters(
14963 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14964 j.m_value.string->size());
14965 break;
14966 }
14967
14968 case value_t::array:
14969 {
14970 // step 1: write control byte and the array size
14971 const auto N = j.m_value.array->size();
14972 if (N <= 0x17)
14973 {
14974 write_number(static_cast<std::uint8_t>(0x80 + N));
14975 }
14976 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14977 {
14978 oa->write_character(to_char_type(0x98));
14979 write_number(static_cast<std::uint8_t>(N));
14980 }
14981 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14982 {
14983 oa->write_character(to_char_type(0x99));
14984 write_number(static_cast<std::uint16_t>(N));
14985 }
14986 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14987 {
14988 oa->write_character(to_char_type(0x9A));
14989 write_number(static_cast<std::uint32_t>(N));
14990 }
14991 // LCOV_EXCL_START
14992 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14993 {
14994 oa->write_character(to_char_type(0x9B));
14995 write_number(static_cast<std::uint64_t>(N));
14996 }
14997 // LCOV_EXCL_STOP
14998
14999 // step 2: write each element
15000 for (const auto& el : *j.m_value.array)
15001 {
15002 write_cbor(el);
15003 }
15004 break;
15005 }
15006
15007 case value_t::binary:
15008 {
15009 if (j.m_value.binary->has_subtype())
15010 {
15011 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
15012 {
15013 write_number(static_cast<std::uint8_t>(0xd8));
15014 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
15015 }
15016 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
15017 {
15018 write_number(static_cast<std::uint8_t>(0xd9));
15019 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
15020 }
15021 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
15022 {
15023 write_number(static_cast<std::uint8_t>(0xda));
15024 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
15025 }
15026 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
15027 {
15028 write_number(static_cast<std::uint8_t>(0xdb));
15029 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
15030 }
15031 }
15032
15033 // step 1: write control byte and the binary array size
15034 const auto N = j.m_value.binary->size();
15035 if (N <= 0x17)
15036 {
15037 write_number(static_cast<std::uint8_t>(0x40 + N));
15038 }
15039 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15040 {
15041 oa->write_character(to_char_type(0x58));
15042 write_number(static_cast<std::uint8_t>(N));
15043 }
15044 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15045 {
15046 oa->write_character(to_char_type(0x59));
15047 write_number(static_cast<std::uint16_t>(N));
15048 }
15049 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15050 {
15051 oa->write_character(to_char_type(0x5A));
15052 write_number(static_cast<std::uint32_t>(N));
15053 }
15054 // LCOV_EXCL_START
15055 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15056 {
15057 oa->write_character(to_char_type(0x5B));
15058 write_number(static_cast<std::uint64_t>(N));
15059 }
15060 // LCOV_EXCL_STOP
15061
15062 // step 2: write each element
15063 oa->write_characters(
15064 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15065 N);
15066
15067 break;
15068 }
15069
15070 case value_t::object:
15071 {
15072 // step 1: write control byte and the object size
15073 const auto N = j.m_value.object->size();
15074 if (N <= 0x17)
15075 {
15076 write_number(static_cast<std::uint8_t>(0xA0 + N));
15077 }
15078 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15079 {
15080 oa->write_character(to_char_type(0xB8));
15081 write_number(static_cast<std::uint8_t>(N));
15082 }
15083 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15084 {
15085 oa->write_character(to_char_type(0xB9));
15086 write_number(static_cast<std::uint16_t>(N));
15087 }
15088 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15089 {
15090 oa->write_character(to_char_type(0xBA));
15091 write_number(static_cast<std::uint32_t>(N));
15092 }
15093 // LCOV_EXCL_START
15094 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15095 {
15096 oa->write_character(to_char_type(0xBB));
15097 write_number(static_cast<std::uint64_t>(N));
15098 }
15099 // LCOV_EXCL_STOP
15100
15101 // step 2: write each element
15102 for (const auto& el : *j.m_value.object)
15103 {
15104 write_cbor(el.first);
15105 write_cbor(el.second);
15106 }
15107 break;
15108 }
15109
15110 case value_t::discarded:
15111 default:
15112 break;
15113 }
15114 }
15115
15119 void write_msgpack(const BasicJsonType& j)
15120 {
15121 switch (j.type())
15122 {
15123 case value_t::null: // nil
15124 {
15125 oa->write_character(to_char_type(0xC0));
15126 break;
15127 }
15128
15129 case value_t::boolean: // true and false
15130 {
15131 oa->write_character(j.m_value.boolean
15132 ? to_char_type(0xC3)
15133 : to_char_type(0xC2));
15134 break;
15135 }
15136
15137 case value_t::number_integer:
15138 {
15139 if (j.m_value.number_integer >= 0)
15140 {
15141 // MessagePack does not differentiate between positive
15142 // signed integers and unsigned integers. Therefore, we used
15143 // the code from the value_t::number_unsigned case here.
15144 if (j.m_value.number_unsigned < 128)
15145 {
15146 // positive fixnum
15147 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15148 }
15149 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15150 {
15151 // uint 8
15152 oa->write_character(to_char_type(0xCC));
15153 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15154 }
15155 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15156 {
15157 // uint 16
15158 oa->write_character(to_char_type(0xCD));
15159 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
15160 }
15161 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15162 {
15163 // uint 32
15164 oa->write_character(to_char_type(0xCE));
15165 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
15166 }
15167 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15168 {
15169 // uint 64
15170 oa->write_character(to_char_type(0xCF));
15171 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
15172 }
15173 }
15174 else
15175 {
15176 if (j.m_value.number_integer >= -32)
15177 {
15178 // negative fixnum
15179 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
15180 }
15181 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
15182 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15183 {
15184 // int 8
15185 oa->write_character(to_char_type(0xD0));
15186 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
15187 }
15188 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
15189 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15190 {
15191 // int 16
15192 oa->write_character(to_char_type(0xD1));
15193 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
15194 }
15195 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
15196 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15197 {
15198 // int 32
15199 oa->write_character(to_char_type(0xD2));
15200 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
15201 }
15202 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
15203 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15204 {
15205 // int 64
15206 oa->write_character(to_char_type(0xD3));
15207 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
15208 }
15209 }
15210 break;
15211 }
15212
15213 case value_t::number_unsigned:
15214 {
15215 if (j.m_value.number_unsigned < 128)
15216 {
15217 // positive fixnum
15218 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15219 }
15220 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15221 {
15222 // uint 8
15223 oa->write_character(to_char_type(0xCC));
15224 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15225 }
15226 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15227 {
15228 // uint 16
15229 oa->write_character(to_char_type(0xCD));
15230 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
15231 }
15232 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15233 {
15234 // uint 32
15235 oa->write_character(to_char_type(0xCE));
15236 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
15237 }
15238 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15239 {
15240 // uint 64
15241 oa->write_character(to_char_type(0xCF));
15242 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
15243 }
15244 break;
15245 }
15246
15247 case value_t::number_float:
15248 {
15249 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
15250 break;
15251 }
15252
15253 case value_t::string:
15254 {
15255 // step 1: write control byte and the string length
15256 const auto N = j.m_value.string->size();
15257 if (N <= 31)
15258 {
15259 // fixstr
15260 write_number(static_cast<std::uint8_t>(0xA0 | N));
15261 }
15262 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15263 {
15264 // str 8
15265 oa->write_character(to_char_type(0xD9));
15266 write_number(static_cast<std::uint8_t>(N));
15267 }
15268 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15269 {
15270 // str 16
15271 oa->write_character(to_char_type(0xDA));
15272 write_number(static_cast<std::uint16_t>(N));
15273 }
15274 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15275 {
15276 // str 32
15277 oa->write_character(to_char_type(0xDB));
15278 write_number(static_cast<std::uint32_t>(N));
15279 }
15280
15281 // step 2: write the string
15282 oa->write_characters(
15283 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15284 j.m_value.string->size());
15285 break;
15286 }
15287
15288 case value_t::array:
15289 {
15290 // step 1: write control byte and the array size
15291 const auto N = j.m_value.array->size();
15292 if (N <= 15)
15293 {
15294 // fixarray
15295 write_number(static_cast<std::uint8_t>(0x90 | N));
15296 }
15297 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15298 {
15299 // array 16
15300 oa->write_character(to_char_type(0xDC));
15301 write_number(static_cast<std::uint16_t>(N));
15302 }
15303 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15304 {
15305 // array 32
15306 oa->write_character(to_char_type(0xDD));
15307 write_number(static_cast<std::uint32_t>(N));
15308 }
15309
15310 // step 2: write each element
15311 for (const auto& el : *j.m_value.array)
15312 {
15313 write_msgpack(el);
15314 }
15315 break;
15316 }
15317
15318 case value_t::binary:
15319 {
15320 // step 0: determine if the binary type has a set subtype to
15321 // determine whether or not to use the ext or fixext types
15322 const bool use_ext = j.m_value.binary->has_subtype();
15323
15324 // step 1: write control byte and the byte string length
15325 const auto N = j.m_value.binary->size();
15326 if (N <= (std::numeric_limits<std::uint8_t>::max)())
15327 {
15328 std::uint8_t output_type{};
15329 bool fixed = true;
15330 if (use_ext)
15331 {
15332 switch (N)
15333 {
15334 case 1:
15335 output_type = 0xD4; // fixext 1
15336 break;
15337 case 2:
15338 output_type = 0xD5; // fixext 2
15339 break;
15340 case 4:
15341 output_type = 0xD6; // fixext 4
15342 break;
15343 case 8:
15344 output_type = 0xD7; // fixext 8
15345 break;
15346 case 16:
15347 output_type = 0xD8; // fixext 16
15348 break;
15349 default:
15350 output_type = 0xC7; // ext 8
15351 fixed = false;
15352 break;
15353 }
15354
15355 }
15356 else
15357 {
15358 output_type = 0xC4; // bin 8
15359 fixed = false;
15360 }
15361
15362 oa->write_character(to_char_type(output_type));
15363 if (!fixed)
15364 {
15365 write_number(static_cast<std::uint8_t>(N));
15366 }
15367 }
15368 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15369 {
15370 std::uint8_t output_type = use_ext
15371 ? 0xC8 // ext 16
15372 : 0xC5; // bin 16
15373
15374 oa->write_character(to_char_type(output_type));
15375 write_number(static_cast<std::uint16_t>(N));
15376 }
15377 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15378 {
15379 std::uint8_t output_type = use_ext
15380 ? 0xC9 // ext 32
15381 : 0xC6; // bin 32
15382
15383 oa->write_character(to_char_type(output_type));
15384 write_number(static_cast<std::uint32_t>(N));
15385 }
15386
15387 // step 1.5: if this is an ext type, write the subtype
15388 if (use_ext)
15389 {
15390 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
15391 }
15392
15393 // step 2: write the byte string
15394 oa->write_characters(
15395 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15396 N);
15397
15398 break;
15399 }
15400
15401 case value_t::object:
15402 {
15403 // step 1: write control byte and the object size
15404 const auto N = j.m_value.object->size();
15405 if (N <= 15)
15406 {
15407 // fixmap
15408 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15409 }
15410 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15411 {
15412 // map 16
15413 oa->write_character(to_char_type(0xDE));
15414 write_number(static_cast<std::uint16_t>(N));
15415 }
15416 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15417 {
15418 // map 32
15419 oa->write_character(to_char_type(0xDF));
15420 write_number(static_cast<std::uint32_t>(N));
15421 }
15422
15423 // step 2: write each element
15424 for (const auto& el : *j.m_value.object)
15425 {
15426 write_msgpack(el.first);
15427 write_msgpack(el.second);
15428 }
15429 break;
15430 }
15431
15432 case value_t::discarded:
15433 default:
15434 break;
15435 }
15436 }
15437
15445 void write_ubjson(const BasicJsonType& j, const bool use_count,
15446 const bool use_type, const bool add_prefix = true,
15447 const bool use_bjdata = false)
15448 {
15449 switch (j.type())
15450 {
15451 case value_t::null:
15452 {
15453 if (add_prefix)
15454 {
15455 oa->write_character(to_char_type('Z'));
15456 }
15457 break;
15458 }
15459
15460 case value_t::boolean:
15461 {
15462 if (add_prefix)
15463 {
15464 oa->write_character(j.m_value.boolean
15465 ? to_char_type('T')
15466 : to_char_type('F'));
15467 }
15468 break;
15469 }
15470
15471 case value_t::number_integer:
15472 {
15473 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
15474 break;
15475 }
15476
15477 case value_t::number_unsigned:
15478 {
15479 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
15480 break;
15481 }
15482
15483 case value_t::number_float:
15484 {
15485 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
15486 break;
15487 }
15488
15489 case value_t::string:
15490 {
15491 if (add_prefix)
15492 {
15493 oa->write_character(to_char_type('S'));
15494 }
15495 write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata);
15496 oa->write_characters(
15497 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15498 j.m_value.string->size());
15499 break;
15500 }
15501
15502 case value_t::array:
15503 {
15504 if (add_prefix)
15505 {
15506 oa->write_character(to_char_type('['));
15507 }
15508
15509 bool prefix_required = true;
15510 if (use_type && !j.m_value.array->empty())
15511 {
15512 JSON_ASSERT(use_count);
15513 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15514 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15515 [this, first_prefix, use_bjdata](const BasicJsonType & v)
15516 {
15517 return ubjson_prefix(v, use_bjdata) == first_prefix;
15518 });
15519
15520 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15521
15522 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15523 {
15524 prefix_required = false;
15525 oa->write_character(to_char_type('$'));
15526 oa->write_character(first_prefix);
15527 }
15528 }
15529
15530 if (use_count)
15531 {
15532 oa->write_character(to_char_type('#'));
15533 write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata);
15534 }
15535
15536 for (const auto& el : *j.m_value.array)
15537 {
15538 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15539 }
15540
15541 if (!use_count)
15542 {
15543 oa->write_character(to_char_type(']'));
15544 }
15545
15546 break;
15547 }
15548
15549 case value_t::binary:
15550 {
15551 if (add_prefix)
15552 {
15553 oa->write_character(to_char_type('['));
15554 }
15555
15556 if (use_type && !j.m_value.binary->empty())
15557 {
15558 JSON_ASSERT(use_count);
15559 oa->write_character(to_char_type('$'));
15560 oa->write_character('U');
15561 }
15562
15563 if (use_count)
15564 {
15565 oa->write_character(to_char_type('#'));
15566 write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata);
15567 }
15568
15569 if (use_type)
15570 {
15571 oa->write_characters(
15572 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15573 j.m_value.binary->size());
15574 }
15575 else
15576 {
15577 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
15578 {
15579 oa->write_character(to_char_type('U'));
15580 oa->write_character(j.m_value.binary->data()[i]);
15581 }
15582 }
15583
15584 if (!use_count)
15585 {
15586 oa->write_character(to_char_type(']'));
15587 }
15588
15589 break;
15590 }
15591
15592 case value_t::object:
15593 {
15594 if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end())
15595 {
15596 if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15597 {
15598 break;
15599 }
15600 }
15601
15602 if (add_prefix)
15603 {
15604 oa->write_character(to_char_type('{'));
15605 }
15606
15607 bool prefix_required = true;
15608 if (use_type && !j.m_value.object->empty())
15609 {
15610 JSON_ASSERT(use_count);
15611 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15612 const bool same_prefix = std::all_of(j.begin(), j.end(),
15613 [this, first_prefix, use_bjdata](const BasicJsonType & v)
15614 {
15615 return ubjson_prefix(v, use_bjdata) == first_prefix;
15616 });
15617
15618 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15619
15620 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15621 {
15622 prefix_required = false;
15623 oa->write_character(to_char_type('$'));
15624 oa->write_character(first_prefix);
15625 }
15626 }
15627
15628 if (use_count)
15629 {
15630 oa->write_character(to_char_type('#'));
15631 write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata);
15632 }
15633
15634 for (const auto& el : *j.m_value.object)
15635 {
15636 write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15637 oa->write_characters(
15638 reinterpret_cast<const CharType*>(el.first.c_str()),
15639 el.first.size());
15640 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15641 }
15642
15643 if (!use_count)
15644 {
15645 oa->write_character(to_char_type('}'));
15646 }
15647
15648 break;
15649 }
15650
15651 case value_t::discarded:
15652 default:
15653 break;
15654 }
15655 }
15656
15657 private:
15659 // BSON //
15661
15666 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
15667 {
15668 const auto it = name.find(static_cast<typename string_t::value_type>(0));
15669 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
15670 {
15671 JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
15672 static_cast<void>(j);
15673 }
15674
15675 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
15676 }
15677
15682 const std::uint8_t element_type)
15683 {
15684 oa->write_character(to_char_type(element_type)); // boolean
15685 oa->write_characters(
15686 reinterpret_cast<const CharType*>(name.c_str()),
15687 name.size() + 1u);
15688 }
15689
15694 const bool value)
15695 {
15696 write_bson_entry_header(name, 0x08);
15697 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
15698 }
15699
15704 const double value)
15705 {
15706 write_bson_entry_header(name, 0x01);
15707 write_number<double>(value, true);
15708 }
15709
15713 static std::size_t calc_bson_string_size(const string_t& value)
15714 {
15715 return sizeof(std::int32_t) + value.size() + 1ul;
15716 }
15717
15722 const string_t& value)
15723 {
15724 write_bson_entry_header(name, 0x02);
15725
15726 write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15727 oa->write_characters(
15728 reinterpret_cast<const CharType*>(value.c_str()),
15729 value.size() + 1);
15730 }
15731
15736 {
15737 write_bson_entry_header(name, 0x0A);
15738 }
15739
15743 static std::size_t calc_bson_integer_size(const std::int64_t value)
15744 {
15745 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
15746 ? sizeof(std::int32_t)
15747 : sizeof(std::int64_t);
15748 }
15749
15754 const std::int64_t value)
15755 {
15756 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
15757 {
15758 write_bson_entry_header(name, 0x10); // int32
15759 write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
15760 }
15761 else
15762 {
15763 write_bson_entry_header(name, 0x12); // int64
15764 write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
15765 }
15766 }
15767
15771 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
15772 {
15773 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15774 ? sizeof(std::int32_t)
15775 : sizeof(std::int64_t);
15776 }
15777
15782 const BasicJsonType& j)
15783 {
15784 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15785 {
15786 write_bson_entry_header(name, 0x10 /* int32 */);
15787 write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true);
15788 }
15789 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15790 {
15791 write_bson_entry_header(name, 0x12 /* int64 */);
15792 write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true);
15793 }
15794 else
15795 {
15796 JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
15797 }
15798 }
15799
15804 const typename BasicJsonType::object_t& value)
15805 {
15806 write_bson_entry_header(name, 0x03); // object
15807 write_bson_object(value);
15808 }
15809
15813 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
15814 {
15815 std::size_t array_index = 0ul;
15816
15817 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
15818 {
15819 return result + calc_bson_element_size(std::to_string(array_index++), el);
15820 });
15821
15822 return sizeof(std::int32_t) + embedded_document_size + 1ul;
15823 }
15824
15828 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
15829 {
15830 return sizeof(std::int32_t) + value.size() + 1ul;
15831 }
15832
15837 const typename BasicJsonType::array_t& value)
15838 {
15839 write_bson_entry_header(name, 0x04); // array
15840 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
15841
15842 std::size_t array_index = 0ul;
15843
15844 for (const auto& el : value)
15845 {
15846 write_bson_element(std::to_string(array_index++), el);
15847 }
15848
15849 oa->write_character(to_char_type(0x00));
15850 }
15851
15856 const binary_t& value)
15857 {
15858 write_bson_entry_header(name, 0x05);
15859
15860 write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
15861 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
15862
15863 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
15864 }
15865
15870 static std::size_t calc_bson_element_size(const string_t& name,
15871 const BasicJsonType& j)
15872 {
15873 const auto header_size = calc_bson_entry_header_size(name, j);
15874 switch (j.type())
15875 {
15876 case value_t::object:
15877 return header_size + calc_bson_object_size(*j.m_value.object);
15878
15879 case value_t::array:
15880 return header_size + calc_bson_array_size(*j.m_value.array);
15881
15882 case value_t::binary:
15883 return header_size + calc_bson_binary_size(*j.m_value.binary);
15884
15885 case value_t::boolean:
15886 return header_size + 1ul;
15887
15888 case value_t::number_float:
15889 return header_size + 8ul;
15890
15891 case value_t::number_integer:
15892 return header_size + calc_bson_integer_size(j.m_value.number_integer);
15893
15894 case value_t::number_unsigned:
15895 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
15896
15897 case value_t::string:
15898 return header_size + calc_bson_string_size(*j.m_value.string);
15899
15900 case value_t::null:
15901 return header_size + 0ul;
15902
15903 // LCOV_EXCL_START
15904 case value_t::discarded:
15905 default:
15906 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15907 return 0ul;
15908 // LCOV_EXCL_STOP
15909 }
15910 }
15911
15919 const BasicJsonType& j)
15920 {
15921 switch (j.type())
15922 {
15923 case value_t::object:
15924 return write_bson_object_entry(name, *j.m_value.object);
15925
15926 case value_t::array:
15927 return write_bson_array(name, *j.m_value.array);
15928
15929 case value_t::binary:
15930 return write_bson_binary(name, *j.m_value.binary);
15931
15932 case value_t::boolean:
15933 return write_bson_boolean(name, j.m_value.boolean);
15934
15935 case value_t::number_float:
15936 return write_bson_double(name, j.m_value.number_float);
15937
15938 case value_t::number_integer:
15939 return write_bson_integer(name, j.m_value.number_integer);
15940
15941 case value_t::number_unsigned:
15942 return write_bson_unsigned(name, j);
15943
15944 case value_t::string:
15945 return write_bson_string(name, *j.m_value.string);
15946
15947 case value_t::null:
15948 return write_bson_null(name);
15949
15950 // LCOV_EXCL_START
15951 case value_t::discarded:
15952 default:
15953 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15954 return;
15955 // LCOV_EXCL_STOP
15956 }
15957 }
15958
15965 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
15966 {
15967 std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
15968 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
15969 {
15970 return result += calc_bson_element_size(el.first, el.second);
15971 });
15972
15973 return sizeof(std::int32_t) + document_size + 1ul;
15974 }
15975
15980 void write_bson_object(const typename BasicJsonType::object_t& value)
15981 {
15982 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
15983
15984 for (const auto& el : value)
15985 {
15986 write_bson_element(el.first, el.second);
15987 }
15988
15989 oa->write_character(to_char_type(0x00));
15990 }
15991
15993 // CBOR //
15995
15996 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
15997 {
15998 return to_char_type(0xFA); // Single-Precision Float
15999 }
16000
16001 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
16002 {
16003 return to_char_type(0xFB); // Double-Precision Float
16004 }
16005
16007 // MsgPack //
16009
16010 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
16011 {
16012 return to_char_type(0xCA); // float 32
16013 }
16014
16015 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
16016 {
16017 return to_char_type(0xCB); // float 64
16018 }
16019
16021 // UBJSON //
16023
16024 // UBJSON: write number (floating point)
16025 template<typename NumberType, typename std::enable_if<
16026 std::is_floating_point<NumberType>::value, int>::type = 0>
16027 void write_number_with_ubjson_prefix(const NumberType n,
16028 const bool add_prefix,
16029 const bool use_bjdata)
16030 {
16031 if (add_prefix)
16032 {
16033 oa->write_character(get_ubjson_float_prefix(n));
16034 }
16035 write_number(n, use_bjdata);
16036 }
16037
16038 // UBJSON: write number (unsigned integer)
16039 template<typename NumberType, typename std::enable_if<
16040 std::is_unsigned<NumberType>::value, int>::type = 0>
16041 void write_number_with_ubjson_prefix(const NumberType n,
16042 const bool add_prefix,
16043 const bool use_bjdata)
16044 {
16045 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16046 {
16047 if (add_prefix)
16048 {
16049 oa->write_character(to_char_type('i')); // int8
16050 }
16051 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16052 }
16053 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
16054 {
16055 if (add_prefix)
16056 {
16057 oa->write_character(to_char_type('U')); // uint8
16058 }
16059 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16060 }
16061 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16062 {
16063 if (add_prefix)
16064 {
16065 oa->write_character(to_char_type('I')); // int16
16066 }
16067 write_number(static_cast<std::int16_t>(n), use_bjdata);
16068 }
16069 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
16070 {
16071 if (add_prefix)
16072 {
16073 oa->write_character(to_char_type('u')); // uint16 - bjdata only
16074 }
16075 write_number(static_cast<std::uint16_t>(n), use_bjdata);
16076 }
16077 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16078 {
16079 if (add_prefix)
16080 {
16081 oa->write_character(to_char_type('l')); // int32
16082 }
16083 write_number(static_cast<std::int32_t>(n), use_bjdata);
16084 }
16085 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
16086 {
16087 if (add_prefix)
16088 {
16089 oa->write_character(to_char_type('m')); // uint32 - bjdata only
16090 }
16091 write_number(static_cast<std::uint32_t>(n), use_bjdata);
16092 }
16093 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16094 {
16095 if (add_prefix)
16096 {
16097 oa->write_character(to_char_type('L')); // int64
16098 }
16099 write_number(static_cast<std::int64_t>(n), use_bjdata);
16100 }
16101 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
16102 {
16103 if (add_prefix)
16104 {
16105 oa->write_character(to_char_type('M')); // uint64 - bjdata only
16106 }
16107 write_number(static_cast<std::uint64_t>(n), use_bjdata);
16108 }
16109 else
16110 {
16111 if (add_prefix)
16112 {
16113 oa->write_character(to_char_type('H')); // high-precision number
16114 }
16115
16116 const auto number = BasicJsonType(n).dump();
16117 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16118 for (std::size_t i = 0; i < number.size(); ++i)
16119 {
16120 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16121 }
16122 }
16123 }
16124
16125 // UBJSON: write number (signed integer)
16126 template < typename NumberType, typename std::enable_if <
16127 std::is_signed<NumberType>::value&&
16128 !std::is_floating_point<NumberType>::value, int >::type = 0 >
16129 void write_number_with_ubjson_prefix(const NumberType n,
16130 const bool add_prefix,
16131 const bool use_bjdata)
16132 {
16133 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
16134 {
16135 if (add_prefix)
16136 {
16137 oa->write_character(to_char_type('i')); // int8
16138 }
16139 write_number(static_cast<std::int8_t>(n), use_bjdata);
16140 }
16141 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
16142 {
16143 if (add_prefix)
16144 {
16145 oa->write_character(to_char_type('U')); // uint8
16146 }
16147 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16148 }
16149 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
16150 {
16151 if (add_prefix)
16152 {
16153 oa->write_character(to_char_type('I')); // int16
16154 }
16155 write_number(static_cast<std::int16_t>(n), use_bjdata);
16156 }
16157 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
16158 {
16159 if (add_prefix)
16160 {
16161 oa->write_character(to_char_type('u')); // uint16 - bjdata only
16162 }
16163 write_number(static_cast<uint16_t>(n), use_bjdata);
16164 }
16165 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
16166 {
16167 if (add_prefix)
16168 {
16169 oa->write_character(to_char_type('l')); // int32
16170 }
16171 write_number(static_cast<std::int32_t>(n), use_bjdata);
16172 }
16173 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
16174 {
16175 if (add_prefix)
16176 {
16177 oa->write_character(to_char_type('m')); // uint32 - bjdata only
16178 }
16179 write_number(static_cast<uint32_t>(n), use_bjdata);
16180 }
16181 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
16182 {
16183 if (add_prefix)
16184 {
16185 oa->write_character(to_char_type('L')); // int64
16186 }
16187 write_number(static_cast<std::int64_t>(n), use_bjdata);
16188 }
16189 // LCOV_EXCL_START
16190 else
16191 {
16192 if (add_prefix)
16193 {
16194 oa->write_character(to_char_type('H')); // high-precision number
16195 }
16196
16197 const auto number = BasicJsonType(n).dump();
16198 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16199 for (std::size_t i = 0; i < number.size(); ++i)
16200 {
16201 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16202 }
16203 }
16204 // LCOV_EXCL_STOP
16205 }
16206
16210 CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
16211 {
16212 switch (j.type())
16213 {
16214 case value_t::null:
16215 return 'Z';
16216
16217 case value_t::boolean:
16218 return j.m_value.boolean ? 'T' : 'F';
16219
16220 case value_t::number_integer:
16221 {
16222 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
16223 {
16224 return 'i';
16225 }
16226 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
16227 {
16228 return 'U';
16229 }
16230 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
16231 {
16232 return 'I';
16233 }
16234 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
16235 {
16236 return 'u';
16237 }
16238 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
16239 {
16240 return 'l';
16241 }
16242 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
16243 {
16244 return 'm';
16245 }
16246 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
16247 {
16248 return 'L';
16249 }
16250 // anything else is treated as high-precision number
16251 return 'H'; // LCOV_EXCL_LINE
16252 }
16253
16254 case value_t::number_unsigned:
16255 {
16256 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16257 {
16258 return 'i';
16259 }
16260 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
16261 {
16262 return 'U';
16263 }
16264 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16265 {
16266 return 'I';
16267 }
16268 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
16269 {
16270 return 'u';
16271 }
16272 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16273 {
16274 return 'l';
16275 }
16276 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
16277 {
16278 return 'm';
16279 }
16280 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16281 {
16282 return 'L';
16283 }
16284 if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16285 {
16286 return 'M';
16287 }
16288 // anything else is treated as high-precision number
16289 return 'H'; // LCOV_EXCL_LINE
16290 }
16291
16292 case value_t::number_float:
16293 return get_ubjson_float_prefix(j.m_value.number_float);
16294
16295 case value_t::string:
16296 return 'S';
16297
16298 case value_t::array: // fallthrough
16299 case value_t::binary:
16300 return '[';
16301
16302 case value_t::object:
16303 return '{';
16304
16305 case value_t::discarded:
16306 default: // discarded values
16307 return 'N';
16308 }
16309 }
16310
16311 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
16312 {
16313 return 'd'; // float 32
16314 }
16315
16316 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
16317 {
16318 return 'D'; // float 64
16319 }
16320
16324 bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
16325 {
16326 std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
16327 {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
16328 };
16329
16330 string_t key = "_ArrayType_";
16331 auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
16332 if (it == bjdtype.end())
16333 {
16334 return true;
16335 }
16336 CharType dtype = it->second;
16337
16338 key = "_ArraySize_";
16339 std::size_t len = (value.at(key).empty() ? 0 : 1);
16340 for (const auto& el : value.at(key))
16341 {
16342 len *= static_cast<std::size_t>(el.m_value.number_unsigned);
16343 }
16344
16345 key = "_ArrayData_";
16346 if (value.at(key).size() != len)
16347 {
16348 return true;
16349 }
16350
16351 oa->write_character('[');
16352 oa->write_character('$');
16353 oa->write_character(dtype);
16354 oa->write_character('#');
16355
16356 key = "_ArraySize_";
16357 write_ubjson(value.at(key), use_count, use_type, true, true);
16358
16359 key = "_ArrayData_";
16360 if (dtype == 'U' || dtype == 'C')
16361 {
16362 for (const auto& el : value.at(key))
16363 {
16364 write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true);
16365 }
16366 }
16367 else if (dtype == 'i')
16368 {
16369 for (const auto& el : value.at(key))
16370 {
16371 write_number(static_cast<std::int8_t>(el.m_value.number_integer), true);
16372 }
16373 }
16374 else if (dtype == 'u')
16375 {
16376 for (const auto& el : value.at(key))
16377 {
16378 write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true);
16379 }
16380 }
16381 else if (dtype == 'I')
16382 {
16383 for (const auto& el : value.at(key))
16384 {
16385 write_number(static_cast<std::int16_t>(el.m_value.number_integer), true);
16386 }
16387 }
16388 else if (dtype == 'm')
16389 {
16390 for (const auto& el : value.at(key))
16391 {
16392 write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true);
16393 }
16394 }
16395 else if (dtype == 'l')
16396 {
16397 for (const auto& el : value.at(key))
16398 {
16399 write_number(static_cast<std::int32_t>(el.m_value.number_integer), true);
16400 }
16401 }
16402 else if (dtype == 'M')
16403 {
16404 for (const auto& el : value.at(key))
16405 {
16406 write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true);
16407 }
16408 }
16409 else if (dtype == 'L')
16410 {
16411 for (const auto& el : value.at(key))
16412 {
16413 write_number(static_cast<std::int64_t>(el.m_value.number_integer), true);
16414 }
16415 }
16416 else if (dtype == 'd')
16417 {
16418 for (const auto& el : value.at(key))
16419 {
16420 write_number(static_cast<float>(el.m_value.number_float), true);
16421 }
16422 }
16423 else if (dtype == 'D')
16424 {
16425 for (const auto& el : value.at(key))
16426 {
16427 write_number(static_cast<double>(el.m_value.number_float), true);
16428 }
16429 }
16430 return false;
16431 }
16432
16434 // Utility functions //
16436
16437 /*
16438 @brief write a number to output input
16439 @param[in] n number of type @a NumberType
16440 @param[in] OutputIsLittleEndian Set to true if output data is
16441 required to be little endian
16442 @tparam NumberType the type of the number
16443
16444 @note This function needs to respect the system's endianness, because bytes
16445 in CBOR, MessagePack, and UBJSON are stored in network order (big
16446 endian) and therefore need reordering on little endian systems.
16447 On the other hand, BSON and BJData use little endian and should reorder
16448 on big endian systems.
16449 */
16450 template<typename NumberType>
16451 void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16452 {
16453 // step 1: write number to array of length NumberType
16454 std::array<CharType, sizeof(NumberType)> vec{};
16455 std::memcpy(vec.data(), &n, sizeof(NumberType));
16456
16457 // step 2: write array to output (with possible reordering)
16458 if (is_little_endian != OutputIsLittleEndian)
16459 {
16460 // reverse byte order prior to conversion if necessary
16461 std::reverse(vec.begin(), vec.end());
16462 }
16463
16464 oa->write_characters(vec.data(), sizeof(NumberType));
16465 }
16466
16468 {
16469#ifdef __GNUC__
16470#pragma GCC diagnostic push
16471#pragma GCC diagnostic ignored "-Wfloat-equal"
16472#endif
16473 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16474 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16475 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16476 {
16477 oa->write_character(format == detail::input_format_t::cbor
16478 ? get_cbor_float_prefix(static_cast<float>(n))
16479 : get_msgpack_float_prefix(static_cast<float>(n)));
16480 write_number(static_cast<float>(n));
16481 }
16482 else
16483 {
16484 oa->write_character(format == detail::input_format_t::cbor
16485 ? get_cbor_float_prefix(n)
16486 : get_msgpack_float_prefix(n));
16487 write_number(n);
16488 }
16489#ifdef __GNUC__
16490#pragma GCC diagnostic pop
16491#endif
16492 }
16493
16494 public:
16495 // The following to_char_type functions are implement the conversion
16496 // between uint8_t and CharType. In case CharType is not unsigned,
16497 // such a conversion is required to allow values greater than 128.
16498 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16499 template < typename C = CharType,
16500 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
16501 static constexpr CharType to_char_type(std::uint8_t x) noexcept
16502 {
16503 return *reinterpret_cast<char*>(&x);
16504 }
16505
16506 template < typename C = CharType,
16507 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
16508 static CharType to_char_type(std::uint8_t x) noexcept
16509 {
16510 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16511 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16512 CharType result;
16513 std::memcpy(&result, &x, sizeof(x));
16514 return result;
16515 }
16516
16517 template<typename C = CharType,
16519 static constexpr CharType to_char_type(std::uint8_t x) noexcept
16520 {
16521 return x;
16522 }
16523
16524 template < typename InputCharType, typename C = CharType,
16525 enable_if_t <
16526 std::is_signed<C>::value &&
16527 std::is_signed<char>::value &&
16528 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
16529 > * = nullptr >
16530 static constexpr CharType to_char_type(InputCharType x) noexcept
16531 {
16532 return x;
16533 }
16534
16535 private:
16537 const bool is_little_endian = little_endianness();
16538
16541};
16542
16543} // namespace detail
16545
16546// #include <nlohmann/detail/output/output_adapters.hpp>
16547
16548// #include <nlohmann/detail/output/serializer.hpp>
16549// __ _____ _____ _____
16550// __| | __| | | | JSON for Modern C++
16551// | | |__ | | | | | | version 3.11.1
16552// |_____|_____|_____|_|___| https://github.com/nlohmann/json
16553//
16554// SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
16555// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16556// SPDX-License-Identifier: MIT
16557
16558
16559
16560#include <algorithm> // reverse, remove, fill, find, none_of
16561#include <array> // array
16562#include <clocale> // localeconv, lconv
16563#include <cmath> // labs, isfinite, isnan, signbit
16564#include <cstddef> // size_t, ptrdiff_t
16565#include <cstdint> // uint8_t
16566#include <cstdio> // snprintf
16567#include <limits> // numeric_limits
16568#include <string> // string, char_traits
16569#include <iomanip> // setfill, setw
16570#include <type_traits> // is_same
16571#include <utility> // move
16572
16573// #include <nlohmann/detail/conversions/to_chars.hpp>
16574// __ _____ _____ _____
16575// __| | __| | | | JSON for Modern C++
16576// | | |__ | | | | | | version 3.11.1
16577// |_____|_____|_____|_|___| https://github.com/nlohmann/json
16578//
16579// SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
16580// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16581// SPDX-License-Identifier: MIT
16582
16583
16584
16585#include <array> // array
16586#include <cmath> // signbit, isfinite
16587#include <cstdint> // intN_t, uintN_t
16588#include <cstring> // memcpy, memmove
16589#include <limits> // numeric_limits
16590#include <type_traits> // conditional
16591
16592// #include <nlohmann/detail/macro_scope.hpp>
16593
16594
16596namespace detail
16597{
16598
16618namespace dtoa_impl
16619{
16620
16621template<typename Target, typename Source>
16622Target reinterpret_bits(const Source source)
16623{
16624 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16625
16626 Target target;
16627 std::memcpy(&target, &source, sizeof(Source));
16628 return target;
16629}
16630
16631struct diyfp // f * 2^e
16632{
16633 static constexpr int kPrecision = 64; // = q
16634
16635 std::uint64_t f = 0;
16636 int e = 0;
16637
16638 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16639
16644 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16645 {
16646 JSON_ASSERT(x.e == y.e);
16647 JSON_ASSERT(x.f >= y.f);
16648
16649 return {x.f - y.f, x.e};
16650 }
16651
16656 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16657 {
16658 static_assert(kPrecision == 64, "internal error");
16659
16660 // Computes:
16661 // f = round((x.f * y.f) / 2^q)
16662 // e = x.e + y.e + q
16663
16664 // Emulate the 64-bit * 64-bit multiplication:
16665 //
16666 // p = u * v
16667 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
16668 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
16669 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
16670 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
16671 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
16672 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
16673 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
16674 //
16675 // (Since Q might be larger than 2^32 - 1)
16676 //
16677 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
16678 //
16679 // (Q_hi + H does not overflow a 64-bit int)
16680 //
16681 // = p_lo + 2^64 p_hi
16682
16683 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
16684 const std::uint64_t u_hi = x.f >> 32u;
16685 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
16686 const std::uint64_t v_hi = y.f >> 32u;
16687
16688 const std::uint64_t p0 = u_lo * v_lo;
16689 const std::uint64_t p1 = u_lo * v_hi;
16690 const std::uint64_t p2 = u_hi * v_lo;
16691 const std::uint64_t p3 = u_hi * v_hi;
16692
16693 const std::uint64_t p0_hi = p0 >> 32u;
16694 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
16695 const std::uint64_t p1_hi = p1 >> 32u;
16696 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
16697 const std::uint64_t p2_hi = p2 >> 32u;
16698
16699 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
16700
16701 // The full product might now be computed as
16702 //
16703 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
16704 // p_lo = p0_lo + (Q << 32)
16705 //
16706 // But in this particular case here, the full p_lo is not required.
16707 // Effectively we only need to add the highest bit in p_lo to p_hi (and
16708 // Q_hi + 1 does not overflow).
16709
16710 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
16711
16712 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
16713
16714 return {h, x.e + y.e + 64};
16715 }
16716
16721 static diyfp normalize(diyfp x) noexcept
16722 {
16723 JSON_ASSERT(x.f != 0);
16724
16725 while ((x.f >> 63u) == 0)
16726 {
16727 x.f <<= 1u;
16728 x.e--;
16729 }
16730
16731 return x;
16732 }
16733
16738 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
16739 {
16740 const int delta = x.e - target_exponent;
16741
16742 JSON_ASSERT(delta >= 0);
16743 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16744
16745 return {x.f << delta, target_exponent};
16746 }
16747};
16748
16750{
16754};
16755
16762template<typename FloatType>
16764{
16765 JSON_ASSERT(std::isfinite(value));
16766 JSON_ASSERT(value > 0);
16767
16768 // Convert the IEEE representation into a diyfp.
16769 //
16770 // If v is denormal:
16771 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
16772 // If v is normalized:
16773 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
16774
16775 static_assert(std::numeric_limits<FloatType>::is_iec559,
16776 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
16777
16778 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
16779 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
16780 constexpr int kMinExp = 1 - kBias;
16781 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
16782
16783 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
16784
16785 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
16786 const std::uint64_t E = bits >> (kPrecision - 1);
16787 const std::uint64_t F = bits & (kHiddenBit - 1);
16788
16789 const bool is_denormal = E == 0;
16790 const diyfp v = is_denormal
16791 ? diyfp(F, kMinExp)
16792 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
16793
16794 // Compute the boundaries m- and m+ of the floating-point value
16795 // v = f * 2^e.
16796 //
16797 // Determine v- and v+, the floating-point predecessor and successor if v,
16798 // respectively.
16799 //
16800 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
16801 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
16802 //
16803 // v+ = v + 2^e
16804 //
16805 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
16806 // between m- and m+ round to v, regardless of how the input rounding
16807 // algorithm breaks ties.
16808 //
16809 // ---+-------------+-------------+-------------+-------------+--- (A)
16810 // v- m- v m+ v+
16811 //
16812 // -----------------+------+------+-------------+-------------+--- (B)
16813 // v- m- v m+ v+
16814
16815 const bool lower_boundary_is_closer = F == 0 && E > 1;
16816 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
16817 const diyfp m_minus = lower_boundary_is_closer
16818 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
16819 : diyfp(2 * v.f - 1, v.e - 1); // (A)
16820
16821 // Determine the normalized w+ = m+.
16822 const diyfp w_plus = diyfp::normalize(m_plus);
16823
16824 // Determine w- = m- such that e_(w-) = e_(w+).
16825 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
16826
16827 return {diyfp::normalize(v), w_minus, w_plus};
16828}
16829
16830// Given normalized diyfp w, Grisu needs to find a (normalized) cached
16831// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
16832// within a certain range [alpha, gamma] (Definition 3.2 from [1])
16833//
16834// alpha <= e = e_c + e_w + q <= gamma
16835//
16836// or
16837//
16838// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
16839// <= f_c * f_w * 2^gamma
16840//
16841// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
16842//
16843// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
16844//
16845// or
16846//
16847// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
16848//
16849// The choice of (alpha,gamma) determines the size of the table and the form of
16850// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
16851// in practice:
16852//
16853// The idea is to cut the number c * w = f * 2^e into two parts, which can be
16854// processed independently: An integral part p1, and a fractional part p2:
16855//
16856// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
16857// = (f div 2^-e) + (f mod 2^-e) * 2^e
16858// = p1 + p2 * 2^e
16859//
16860// The conversion of p1 into decimal form requires a series of divisions and
16861// modulos by (a power of) 10. These operations are faster for 32-bit than for
16862// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
16863// achieved by choosing
16864//
16865// -e >= 32 or e <= -32 := gamma
16866//
16867// In order to convert the fractional part
16868//
16869// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
16870//
16871// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
16872// d[-i] are extracted in order:
16873//
16874// (10 * p2) div 2^-e = d[-1]
16875// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
16876//
16877// The multiplication by 10 must not overflow. It is sufficient to choose
16878//
16879// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
16880//
16881// Since p2 = f mod 2^-e < 2^-e,
16882//
16883// -e <= 60 or e >= -60 := alpha
16884
16885constexpr int kAlpha = -60;
16886constexpr int kGamma = -32;
16887
16888struct cached_power // c = f * 2^e ~= 10^k
16889{
16890 std::uint64_t f;
16891 int e;
16892 int k;
16893};
16894
16903{
16904 // Now
16905 //
16906 // alpha <= e_c + e + q <= gamma (1)
16907 // ==> f_c * 2^alpha <= c * 2^e * 2^q
16908 //
16909 // and since the c's are normalized, 2^(q-1) <= f_c,
16910 //
16911 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
16912 // ==> 2^(alpha - e - 1) <= c
16913 //
16914 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
16915 //
16916 // k = ceil( log_10( 2^(alpha - e - 1) ) )
16917 // = ceil( (alpha - e - 1) * log_10(2) )
16918 //
16919 // From the paper:
16920 // "In theory the result of the procedure could be wrong since c is rounded,
16921 // and the computation itself is approximated [...]. In practice, however,
16922 // this simple function is sufficient."
16923 //
16924 // For IEEE double precision floating-point numbers converted into
16925 // normalized diyfp's w = f * 2^e, with q = 64,
16926 //
16927 // e >= -1022 (min IEEE exponent)
16928 // -52 (p - 1)
16929 // -52 (p - 1, possibly normalize denormal IEEE numbers)
16930 // -11 (normalize the diyfp)
16931 // = -1137
16932 //
16933 // and
16934 //
16935 // e <= +1023 (max IEEE exponent)
16936 // -52 (p - 1)
16937 // -11 (normalize the diyfp)
16938 // = 960
16939 //
16940 // This binary exponent range [-1137,960] results in a decimal exponent
16941 // range [-307,324]. One does not need to store a cached power for each
16942 // k in this range. For each such k it suffices to find a cached power
16943 // such that the exponent of the product lies in [alpha,gamma].
16944 // This implies that the difference of the decimal exponents of adjacent
16945 // table entries must be less than or equal to
16946 //
16947 // floor( (gamma - alpha) * log_10(2) ) = 8.
16948 //
16949 // (A smaller distance gamma-alpha would require a larger table.)
16950
16951 // NB:
16952 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
16953
16954 constexpr int kCachedPowersMinDecExp = -300;
16955 constexpr int kCachedPowersDecStep = 8;
16956
16957 static constexpr std::array<cached_power, 79> kCachedPowers =
16958 {
16959 {
16960 { 0xAB70FE17C79AC6CA, -1060, -300 },
16961 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
16962 { 0xBE5691EF416BD60C, -1007, -284 },
16963 { 0x8DD01FAD907FFC3C, -980, -276 },
16964 { 0xD3515C2831559A83, -954, -268 },
16965 { 0x9D71AC8FADA6C9B5, -927, -260 },
16966 { 0xEA9C227723EE8BCB, -901, -252 },
16967 { 0xAECC49914078536D, -874, -244 },
16968 { 0x823C12795DB6CE57, -847, -236 },
16969 { 0xC21094364DFB5637, -821, -228 },
16970 { 0x9096EA6F3848984F, -794, -220 },
16971 { 0xD77485CB25823AC7, -768, -212 },
16972 { 0xA086CFCD97BF97F4, -741, -204 },
16973 { 0xEF340A98172AACE5, -715, -196 },
16974 { 0xB23867FB2A35B28E, -688, -188 },
16975 { 0x84C8D4DFD2C63F3B, -661, -180 },
16976 { 0xC5DD44271AD3CDBA, -635, -172 },
16977 { 0x936B9FCEBB25C996, -608, -164 },
16978 { 0xDBAC6C247D62A584, -582, -156 },
16979 { 0xA3AB66580D5FDAF6, -555, -148 },
16980 { 0xF3E2F893DEC3F126, -529, -140 },
16981 { 0xB5B5ADA8AAFF80B8, -502, -132 },
16982 { 0x87625F056C7C4A8B, -475, -124 },
16983 { 0xC9BCFF6034C13053, -449, -116 },
16984 { 0x964E858C91BA2655, -422, -108 },
16985 { 0xDFF9772470297EBD, -396, -100 },
16986 { 0xA6DFBD9FB8E5B88F, -369, -92 },
16987 { 0xF8A95FCF88747D94, -343, -84 },
16988 { 0xB94470938FA89BCF, -316, -76 },
16989 { 0x8A08F0F8BF0F156B, -289, -68 },
16990 { 0xCDB02555653131B6, -263, -60 },
16991 { 0x993FE2C6D07B7FAC, -236, -52 },
16992 { 0xE45C10C42A2B3B06, -210, -44 },
16993 { 0xAA242499697392D3, -183, -36 },
16994 { 0xFD87B5F28300CA0E, -157, -28 },
16995 { 0xBCE5086492111AEB, -130, -20 },
16996 { 0x8CBCCC096F5088CC, -103, -12 },
16997 { 0xD1B71758E219652C, -77, -4 },
16998 { 0x9C40000000000000, -50, 4 },
16999 { 0xE8D4A51000000000, -24, 12 },
17000 { 0xAD78EBC5AC620000, 3, 20 },
17001 { 0x813F3978F8940984, 30, 28 },
17002 { 0xC097CE7BC90715B3, 56, 36 },
17003 { 0x8F7E32CE7BEA5C70, 83, 44 },
17004 { 0xD5D238A4ABE98068, 109, 52 },
17005 { 0x9F4F2726179A2245, 136, 60 },
17006 { 0xED63A231D4C4FB27, 162, 68 },
17007 { 0xB0DE65388CC8ADA8, 189, 76 },
17008 { 0x83C7088E1AAB65DB, 216, 84 },
17009 { 0xC45D1DF942711D9A, 242, 92 },
17010 { 0x924D692CA61BE758, 269, 100 },
17011 { 0xDA01EE641A708DEA, 295, 108 },
17012 { 0xA26DA3999AEF774A, 322, 116 },
17013 { 0xF209787BB47D6B85, 348, 124 },
17014 { 0xB454E4A179DD1877, 375, 132 },
17015 { 0x865B86925B9BC5C2, 402, 140 },
17016 { 0xC83553C5C8965D3D, 428, 148 },
17017 { 0x952AB45CFA97A0B3, 455, 156 },
17018 { 0xDE469FBD99A05FE3, 481, 164 },
17019 { 0xA59BC234DB398C25, 508, 172 },
17020 { 0xF6C69A72A3989F5C, 534, 180 },
17021 { 0xB7DCBF5354E9BECE, 561, 188 },
17022 { 0x88FCF317F22241E2, 588, 196 },
17023 { 0xCC20CE9BD35C78A5, 614, 204 },
17024 { 0x98165AF37B2153DF, 641, 212 },
17025 { 0xE2A0B5DC971F303A, 667, 220 },
17026 { 0xA8D9D1535CE3B396, 694, 228 },
17027 { 0xFB9B7CD9A4A7443C, 720, 236 },
17028 { 0xBB764C4CA7A44410, 747, 244 },
17029 { 0x8BAB8EEFB6409C1A, 774, 252 },
17030 { 0xD01FEF10A657842C, 800, 260 },
17031 { 0x9B10A4E5E9913129, 827, 268 },
17032 { 0xE7109BFBA19C0C9D, 853, 276 },
17033 { 0xAC2820D9623BF429, 880, 284 },
17034 { 0x80444B5E7AA7CF85, 907, 292 },
17035 { 0xBF21E44003ACDD2D, 933, 300 },
17036 { 0x8E679C2F5E44FF8F, 960, 308 },
17037 { 0xD433179D9C8CB841, 986, 316 },
17038 { 0x9E19DB92B4E31BA9, 1013, 324 },
17039 }
17040 };
17041
17042 // This computation gives exactly the same results for k as
17043 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
17044 // for |e| <= 1500, but doesn't require floating-point operations.
17045 // NB: log_10(2) ~= 78913 / 2^18
17046 JSON_ASSERT(e >= -1500);
17047 JSON_ASSERT(e <= 1500);
17048 const int f = kAlpha - e - 1;
17049 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
17050
17051 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
17052 JSON_ASSERT(index >= 0);
17053 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
17054
17055 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
17056 JSON_ASSERT(kAlpha <= cached.e + e + 64);
17057 JSON_ASSERT(kGamma >= cached.e + e + 64);
17058
17059 return cached;
17060}
17061
17066inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
17067{
17068 // LCOV_EXCL_START
17069 if (n >= 1000000000)
17070 {
17071 pow10 = 1000000000;
17072 return 10;
17073 }
17074 // LCOV_EXCL_STOP
17075 if (n >= 100000000)
17076 {
17077 pow10 = 100000000;
17078 return 9;
17079 }
17080 if (n >= 10000000)
17081 {
17082 pow10 = 10000000;
17083 return 8;
17084 }
17085 if (n >= 1000000)
17086 {
17087 pow10 = 1000000;
17088 return 7;
17089 }
17090 if (n >= 100000)
17091 {
17092 pow10 = 100000;
17093 return 6;
17094 }
17095 if (n >= 10000)
17096 {
17097 pow10 = 10000;
17098 return 5;
17099 }
17100 if (n >= 1000)
17101 {
17102 pow10 = 1000;
17103 return 4;
17104 }
17105 if (n >= 100)
17106 {
17107 pow10 = 100;
17108 return 3;
17109 }
17110 if (n >= 10)
17111 {
17112 pow10 = 10;
17113 return 2;
17114 }
17115
17116 pow10 = 1;
17117 return 1;
17118}
17119
17120inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
17121 std::uint64_t rest, std::uint64_t ten_k)
17122{
17123 JSON_ASSERT(len >= 1);
17124 JSON_ASSERT(dist <= delta);
17125 JSON_ASSERT(rest <= delta);
17126 JSON_ASSERT(ten_k > 0);
17127
17128 // <--------------------------- delta ---->
17129 // <---- dist --------->
17130 // --------------[------------------+-------------------]--------------
17131 // M- w M+
17132 //
17133 // ten_k
17134 // <------>
17135 // <---- rest ---->
17136 // --------------[------------------+----+--------------]--------------
17137 // w V
17138 // = buf * 10^k
17139 //
17140 // ten_k represents a unit-in-the-last-place in the decimal representation
17141 // stored in buf.
17142 // Decrement buf by ten_k while this takes buf closer to w.
17143
17144 // The tests are written in this order to avoid overflow in unsigned
17145 // integer arithmetic.
17146
17147 while (rest < dist
17148 && delta - rest >= ten_k
17149 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
17150 {
17151 JSON_ASSERT(buf[len - 1] != '0');
17152 buf[len - 1]--;
17153 rest += ten_k;
17154 }
17155}
17156
17161inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
17162 diyfp M_minus, diyfp w, diyfp M_plus)
17163{
17164 static_assert(kAlpha >= -60, "internal error");
17165 static_assert(kGamma <= -32, "internal error");
17166
17167 // Generates the digits (and the exponent) of a decimal floating-point
17168 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
17169 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
17170 //
17171 // <--------------------------- delta ---->
17172 // <---- dist --------->
17173 // --------------[------------------+-------------------]--------------
17174 // M- w M+
17175 //
17176 // Grisu2 generates the digits of M+ from left to right and stops as soon as
17177 // V is in [M-,M+].
17178
17179 JSON_ASSERT(M_plus.e >= kAlpha);
17180 JSON_ASSERT(M_plus.e <= kGamma);
17181
17182 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
17183 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
17184
17185 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
17186 //
17187 // M+ = f * 2^e
17188 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
17189 // = ((p1 ) * 2^-e + (p2 )) * 2^e
17190 // = p1 + p2 * 2^e
17191
17192 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
17193
17194 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
17195 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
17196
17197 // 1)
17198 //
17199 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
17200
17201 JSON_ASSERT(p1 > 0);
17202
17203 std::uint32_t pow10{};
17204 const int k = find_largest_pow10(p1, pow10);
17205
17206 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
17207 //
17208 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
17209 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
17210 //
17211 // M+ = p1 + p2 * 2^e
17212 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
17213 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
17214 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
17215 //
17216 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
17217 //
17218 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
17219 //
17220 // but stop as soon as
17221 //
17222 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
17223
17224 int n = k;
17225 while (n > 0)
17226 {
17227 // Invariants:
17228 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
17229 // pow10 = 10^(n-1) <= p1 < 10^n
17230 //
17231 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
17232 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
17233 //
17234 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
17235 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
17236 //
17237 JSON_ASSERT(d <= 9);
17238 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17239 //
17240 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
17241 //
17242 p1 = r;
17243 n--;
17244 //
17245 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
17246 // pow10 = 10^n
17247 //
17248
17249 // Now check if enough digits have been generated.
17250 // Compute
17251 //
17252 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
17253 //
17254 // Note:
17255 // Since rest and delta share the same exponent e, it suffices to
17256 // compare the significands.
17257 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
17258 if (rest <= delta)
17259 {
17260 // V = buffer * 10^n, with M- <= V <= M+.
17261
17262 decimal_exponent += n;
17263
17264 // We may now just stop. But instead look if the buffer could be
17265 // decremented to bring V closer to w.
17266 //
17267 // pow10 = 10^n is now 1 ulp in the decimal representation V.
17268 // The rounding procedure works with diyfp's with an implicit
17269 // exponent of e.
17270 //
17271 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
17272 //
17273 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
17274 grisu2_round(buffer, length, dist, delta, rest, ten_n);
17275
17276 return;
17277 }
17278
17279 pow10 /= 10;
17280 //
17281 // pow10 = 10^(n-1) <= p1 < 10^n
17282 // Invariants restored.
17283 }
17284
17285 // 2)
17286 //
17287 // The digits of the integral part have been generated:
17288 //
17289 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
17290 // = buffer + p2 * 2^e
17291 //
17292 // Now generate the digits of the fractional part p2 * 2^e.
17293 //
17294 // Note:
17295 // No decimal point is generated: the exponent is adjusted instead.
17296 //
17297 // p2 actually represents the fraction
17298 //
17299 // p2 * 2^e
17300 // = p2 / 2^-e
17301 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
17302 //
17303 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
17304 //
17305 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
17306 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
17307 //
17308 // using
17309 //
17310 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
17311 // = ( d) * 2^-e + ( r)
17312 //
17313 // or
17314 // 10^m * p2 * 2^e = d + r * 2^e
17315 //
17316 // i.e.
17317 //
17318 // M+ = buffer + p2 * 2^e
17319 // = buffer + 10^-m * (d + r * 2^e)
17320 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
17321 //
17322 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
17323
17324 JSON_ASSERT(p2 > delta);
17325
17326 int m = 0;
17327 for (;;)
17328 {
17329 // Invariant:
17330 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
17331 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
17332 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
17333 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
17334 //
17335 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
17336 p2 *= 10;
17337 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
17338 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
17339 //
17340 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
17341 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
17342 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
17343 //
17344 JSON_ASSERT(d <= 9);
17345 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17346 //
17347 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
17348 //
17349 p2 = r;
17350 m++;
17351 //
17352 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
17353 // Invariant restored.
17354
17355 // Check if enough digits have been generated.
17356 //
17357 // 10^-m * p2 * 2^e <= delta * 2^e
17358 // p2 * 2^e <= 10^m * delta * 2^e
17359 // p2 <= 10^m * delta
17360 delta *= 10;
17361 dist *= 10;
17362 if (p2 <= delta)
17363 {
17364 break;
17365 }
17366 }
17367
17368 // V = buffer * 10^-m, with M- <= V <= M+.
17369
17370 decimal_exponent -= m;
17371
17372 // 1 ulp in the decimal representation is now 10^-m.
17373 // Since delta and dist are now scaled by 10^m, we need to do the
17374 // same with ulp in order to keep the units in sync.
17375 //
17376 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
17377 //
17378 const std::uint64_t ten_m = one.f;
17379 grisu2_round(buffer, length, dist, delta, p2, ten_m);
17380
17381 // By construction this algorithm generates the shortest possible decimal
17382 // number (Loitsch, Theorem 6.2) which rounds back to w.
17383 // For an input number of precision p, at least
17384 //
17385 // N = 1 + ceil(p * log_10(2))
17386 //
17387 // decimal digits are sufficient to identify all binary floating-point
17388 // numbers (Matula, "In-and-Out conversions").
17389 // This implies that the algorithm does not produce more than N decimal
17390 // digits.
17391 //
17392 // N = 17 for p = 53 (IEEE double precision)
17393 // N = 9 for p = 24 (IEEE single precision)
17394}
17395
17402inline void grisu2(char* buf, int& len, int& decimal_exponent,
17403 diyfp m_minus, diyfp v, diyfp m_plus)
17404{
17405 JSON_ASSERT(m_plus.e == m_minus.e);
17406 JSON_ASSERT(m_plus.e == v.e);
17407
17408 // --------(-----------------------+-----------------------)-------- (A)
17409 // m- v m+
17410 //
17411 // --------------------(-----------+-----------------------)-------- (B)
17412 // m- v m+
17413 //
17414 // First scale v (and m- and m+) such that the exponent is in the range
17415 // [alpha, gamma].
17416
17417 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17418
17419 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17420
17421 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17422 const diyfp w = diyfp::mul(v, c_minus_k);
17423 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17424 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17425
17426 // ----(---+---)---------------(---+---)---------------(---+---)----
17427 // w- w w+
17428 // = c*m- = c*v = c*m+
17429 //
17430 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17431 // w+ are now off by a small amount.
17432 // In fact:
17433 //
17434 // w - v * 10^k < 1 ulp
17435 //
17436 // To account for this inaccuracy, add resp. subtract 1 ulp.
17437 //
17438 // --------+---[---------------(---+---)---------------]---+--------
17439 // w- M- w M+ w+
17440 //
17441 // Now any number in [M-, M+] (bounds included) will round to w when input,
17442 // regardless of how the input rounding algorithm breaks ties.
17443 //
17444 // And digit_gen generates the shortest possible such number in [M-, M+].
17445 // Note that this does not mean that Grisu2 always generates the shortest
17446 // possible number in the interval (m-, m+).
17447 const diyfp M_minus(w_minus.f + 1, w_minus.e);
17448 const diyfp M_plus (w_plus.f - 1, w_plus.e );
17449
17450 decimal_exponent = -cached.k; // = -(-k) = k
17451
17452 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17453}
17454
17460template<typename FloatType>
17462void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17463{
17464 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17465 "internal error: not enough precision");
17466
17467 JSON_ASSERT(std::isfinite(value));
17468 JSON_ASSERT(value > 0);
17469
17470 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17471 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17472 // decimal representations are not exactly "short".
17473 //
17474 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17475 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17476 // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17477 // does.
17478 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17479 // representation using the corresponding std::from_chars function recovers value exactly". That
17480 // indicates that single precision floating-point numbers should be recovered using
17481 // 'std::strtof'.
17482 //
17483 // NB: If the neighbors are computed for single-precision numbers, there is a single float
17484 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17485 // value is off by 1 ulp.
17486#if 0
17487 const boundaries w = compute_boundaries(static_cast<double>(value));
17488#else
17490#endif
17491
17492 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17493}
17494
17502inline char* append_exponent(char* buf, int e)
17503{
17504 JSON_ASSERT(e > -1000);
17505 JSON_ASSERT(e < 1000);
17506
17507 if (e < 0)
17508 {
17509 e = -e;
17510 *buf++ = '-';
17511 }
17512 else
17513 {
17514 *buf++ = '+';
17515 }
17516
17517 auto k = static_cast<std::uint32_t>(e);
17518 if (k < 10)
17519 {
17520 // Always print at least two digits in the exponent.
17521 // This is for compatibility with printf("%g").
17522 *buf++ = '0';
17523 *buf++ = static_cast<char>('0' + k);
17524 }
17525 else if (k < 100)
17526 {
17527 *buf++ = static_cast<char>('0' + k / 10);
17528 k %= 10;
17529 *buf++ = static_cast<char>('0' + k);
17530 }
17531 else
17532 {
17533 *buf++ = static_cast<char>('0' + k / 100);
17534 k %= 100;
17535 *buf++ = static_cast<char>('0' + k / 10);
17536 k %= 10;
17537 *buf++ = static_cast<char>('0' + k);
17538 }
17539
17540 return buf;
17541}
17542
17554inline char* format_buffer(char* buf, int len, int decimal_exponent,
17555 int min_exp, int max_exp)
17556{
17557 JSON_ASSERT(min_exp < 0);
17558 JSON_ASSERT(max_exp > 0);
17559
17560 const int k = len;
17561 const int n = len + decimal_exponent;
17562
17563 // v = buf * 10^(n-k)
17564 // k is the length of the buffer (number of decimal digits)
17565 // n is the position of the decimal point relative to the start of the buffer.
17566
17567 if (k <= n && n <= max_exp)
17568 {
17569 // digits[000]
17570 // len <= max_exp + 2
17571
17572 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17573 // Make it look like a floating-point number (#362, #378)
17574 buf[n + 0] = '.';
17575 buf[n + 1] = '0';
17576 return buf + (static_cast<size_t>(n) + 2);
17577 }
17578
17579 if (0 < n && n <= max_exp)
17580 {
17581 // dig.its
17582 // len <= max_digits10 + 1
17583
17584 JSON_ASSERT(k > n);
17585
17586 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17587 buf[n] = '.';
17588 return buf + (static_cast<size_t>(k) + 1U);
17589 }
17590
17591 if (min_exp < n && n <= 0)
17592 {
17593 // 0.[000]digits
17594 // len <= 2 + (-min_exp - 1) + max_digits10
17595
17596 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17597 buf[0] = '0';
17598 buf[1] = '.';
17599 std::memset(buf + 2, '0', static_cast<size_t>(-n));
17600 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17601 }
17602
17603 if (k == 1)
17604 {
17605 // dE+123
17606 // len <= 1 + 5
17607
17608 buf += 1;
17609 }
17610 else
17611 {
17612 // d.igitsE+123
17613 // len <= max_digits10 + 1 + 5
17614
17615 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17616 buf[1] = '.';
17617 buf += 1 + static_cast<size_t>(k);
17618 }
17619
17620 *buf++ = 'e';
17621 return append_exponent(buf, n - 1);
17622}
17623
17624} // namespace dtoa_impl
17625
17636template<typename FloatType>
17639char* to_chars(char* first, const char* last, FloatType value)
17640{
17641 static_cast<void>(last); // maybe unused - fix warning
17642 JSON_ASSERT(std::isfinite(value));
17643
17644 // Use signbit(value) instead of (value < 0) since signbit works for -0.
17645 if (std::signbit(value))
17646 {
17647 value = -value;
17648 *first++ = '-';
17649 }
17650
17651#ifdef __GNUC__
17652#pragma GCC diagnostic push
17653#pragma GCC diagnostic ignored "-Wfloat-equal"
17654#endif
17655 if (value == 0) // +-0
17656 {
17657 *first++ = '0';
17658 // Make it look like a floating-point number (#362, #378)
17659 *first++ = '.';
17660 *first++ = '0';
17661 return first;
17662 }
17663#ifdef __GNUC__
17664#pragma GCC diagnostic pop
17665#endif
17666
17667 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
17668
17669 // Compute v = buffer * 10^decimal_exponent.
17670 // The decimal digits are stored in the buffer, which needs to be interpreted
17671 // as an unsigned decimal integer.
17672 // len is the length of the buffer, i.e. the number of decimal digits.
17673 int len = 0;
17674 int decimal_exponent = 0;
17675 dtoa_impl::grisu2(first, len, decimal_exponent, value);
17676
17677 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
17678
17679 // Format the buffer like printf("%.*g", prec, value)
17680 constexpr int kMinExp = -4;
17681 // Use digits10 here to increase compatibility with version 2.
17682 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
17683
17684 JSON_ASSERT(last - first >= kMaxExp + 2);
17685 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
17686 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
17687
17688 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
17689}
17690
17691} // namespace detail
17693
17694// #include <nlohmann/detail/exceptions.hpp>
17695
17696// #include <nlohmann/detail/macro_scope.hpp>
17697
17698// #include <nlohmann/detail/meta/cpp_future.hpp>
17699
17700// #include <nlohmann/detail/output/binary_writer.hpp>
17701
17702// #include <nlohmann/detail/output/output_adapters.hpp>
17703
17704// #include <nlohmann/detail/string_concat.hpp>
17705
17706// #include <nlohmann/detail/value_t.hpp>
17707
17708
17710namespace detail
17711{
17712
17714// serialization //
17716
17719{
17720 strict,
17721 replace,
17722 ignore
17723};
17724
17725template<typename BasicJsonType>
17727{
17728 using string_t = typename BasicJsonType::string_t;
17729 using number_float_t = typename BasicJsonType::number_float_t;
17730 using number_integer_t = typename BasicJsonType::number_integer_t;
17731 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17732 using binary_char_t = typename BasicJsonType::binary_t::value_type;
17733 static constexpr std::uint8_t UTF8_ACCEPT = 0;
17734 static constexpr std::uint8_t UTF8_REJECT = 1;
17735
17736 public:
17743 error_handler_t error_handler_ = error_handler_t::strict)
17744 : o(std::move(s))
17745 , loc(std::localeconv())
17746 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
17747 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
17748 , indent_char(ichar)
17749 , indent_string(512, indent_char)
17750 , error_handler(error_handler_)
17751 {}
17752
17753 // delete because of pointer members
17754 serializer(const serializer&) = delete;
17758 ~serializer() = default;
17759
17782 void dump(const BasicJsonType& val,
17783 const bool pretty_print,
17784 const bool ensure_ascii,
17785 const unsigned int indent_step,
17786 const unsigned int current_indent = 0)
17787 {
17788 switch (val.m_type)
17789 {
17790 case value_t::object:
17791 {
17792 if (val.m_value.object->empty())
17793 {
17794 o->write_characters("{}", 2);
17795 return;
17796 }
17797
17798 if (pretty_print)
17799 {
17800 o->write_characters("{\n", 2);
17801
17802 // variable to hold indentation for recursive calls
17803 const auto new_indent = current_indent + indent_step;
17804 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17805 {
17806 indent_string.resize(indent_string.size() * 2, ' ');
17807 }
17808
17809 // first n-1 elements
17810 auto i = val.m_value.object->cbegin();
17811 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17812 {
17813 o->write_characters(indent_string.c_str(), new_indent);
17814 o->write_character('\"');
17815 dump_escaped(i->first, ensure_ascii);
17816 o->write_characters("\": ", 3);
17817 dump(i->second, true, ensure_ascii, indent_step, new_indent);
17818 o->write_characters(",\n", 2);
17819 }
17820
17821 // last element
17822 JSON_ASSERT(i != val.m_value.object->cend());
17823 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17824 o->write_characters(indent_string.c_str(), new_indent);
17825 o->write_character('\"');
17826 dump_escaped(i->first, ensure_ascii);
17827 o->write_characters("\": ", 3);
17828 dump(i->second, true, ensure_ascii, indent_step, new_indent);
17829
17830 o->write_character('\n');
17831 o->write_characters(indent_string.c_str(), current_indent);
17832 o->write_character('}');
17833 }
17834 else
17835 {
17836 o->write_character('{');
17837
17838 // first n-1 elements
17839 auto i = val.m_value.object->cbegin();
17840 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17841 {
17842 o->write_character('\"');
17843 dump_escaped(i->first, ensure_ascii);
17844 o->write_characters("\":", 2);
17845 dump(i->second, false, ensure_ascii, indent_step, current_indent);
17846 o->write_character(',');
17847 }
17848
17849 // last element
17850 JSON_ASSERT(i != val.m_value.object->cend());
17851 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17852 o->write_character('\"');
17853 dump_escaped(i->first, ensure_ascii);
17854 o->write_characters("\":", 2);
17855 dump(i->second, false, ensure_ascii, indent_step, current_indent);
17856
17857 o->write_character('}');
17858 }
17859
17860 return;
17861 }
17862
17863 case value_t::array:
17864 {
17865 if (val.m_value.array->empty())
17866 {
17867 o->write_characters("[]", 2);
17868 return;
17869 }
17870
17871 if (pretty_print)
17872 {
17873 o->write_characters("[\n", 2);
17874
17875 // variable to hold indentation for recursive calls
17876 const auto new_indent = current_indent + indent_step;
17877 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17878 {
17879 indent_string.resize(indent_string.size() * 2, ' ');
17880 }
17881
17882 // first n-1 elements
17883 for (auto i = val.m_value.array->cbegin();
17884 i != val.m_value.array->cend() - 1; ++i)
17885 {
17886 o->write_characters(indent_string.c_str(), new_indent);
17887 dump(*i, true, ensure_ascii, indent_step, new_indent);
17888 o->write_characters(",\n", 2);
17889 }
17890
17891 // last element
17892 JSON_ASSERT(!val.m_value.array->empty());
17893 o->write_characters(indent_string.c_str(), new_indent);
17894 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
17895
17896 o->write_character('\n');
17897 o->write_characters(indent_string.c_str(), current_indent);
17898 o->write_character(']');
17899 }
17900 else
17901 {
17902 o->write_character('[');
17903
17904 // first n-1 elements
17905 for (auto i = val.m_value.array->cbegin();
17906 i != val.m_value.array->cend() - 1; ++i)
17907 {
17908 dump(*i, false, ensure_ascii, indent_step, current_indent);
17909 o->write_character(',');
17910 }
17911
17912 // last element
17913 JSON_ASSERT(!val.m_value.array->empty());
17914 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
17915
17916 o->write_character(']');
17917 }
17918
17919 return;
17920 }
17921
17922 case value_t::string:
17923 {
17924 o->write_character('\"');
17925 dump_escaped(*val.m_value.string, ensure_ascii);
17926 o->write_character('\"');
17927 return;
17928 }
17929
17930 case value_t::binary:
17931 {
17932 if (pretty_print)
17933 {
17934 o->write_characters("{\n", 2);
17935
17936 // variable to hold indentation for recursive calls
17937 const auto new_indent = current_indent + indent_step;
17938 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17939 {
17940 indent_string.resize(indent_string.size() * 2, ' ');
17941 }
17942
17943 o->write_characters(indent_string.c_str(), new_indent);
17944
17945 o->write_characters("\"bytes\": [", 10);
17946
17947 if (!val.m_value.binary->empty())
17948 {
17949 for (auto i = val.m_value.binary->cbegin();
17950 i != val.m_value.binary->cend() - 1; ++i)
17951 {
17952 dump_integer(*i);
17953 o->write_characters(", ", 2);
17954 }
17955 dump_integer(val.m_value.binary->back());
17956 }
17957
17958 o->write_characters("],\n", 3);
17959 o->write_characters(indent_string.c_str(), new_indent);
17960
17961 o->write_characters("\"subtype\": ", 11);
17962 if (val.m_value.binary->has_subtype())
17963 {
17964 dump_integer(val.m_value.binary->subtype());
17965 }
17966 else
17967 {
17968 o->write_characters("null", 4);
17969 }
17970 o->write_character('\n');
17971 o->write_characters(indent_string.c_str(), current_indent);
17972 o->write_character('}');
17973 }
17974 else
17975 {
17976 o->write_characters("{\"bytes\":[", 10);
17977
17978 if (!val.m_value.binary->empty())
17979 {
17980 for (auto i = val.m_value.binary->cbegin();
17981 i != val.m_value.binary->cend() - 1; ++i)
17982 {
17983 dump_integer(*i);
17984 o->write_character(',');
17985 }
17986 dump_integer(val.m_value.binary->back());
17987 }
17988
17989 o->write_characters("],\"subtype\":", 12);
17990 if (val.m_value.binary->has_subtype())
17991 {
17992 dump_integer(val.m_value.binary->subtype());
17993 o->write_character('}');
17994 }
17995 else
17996 {
17997 o->write_characters("null}", 5);
17998 }
17999 }
18000 return;
18001 }
18002
18003 case value_t::boolean:
18004 {
18005 if (val.m_value.boolean)
18006 {
18007 o->write_characters("true", 4);
18008 }
18009 else
18010 {
18011 o->write_characters("false", 5);
18012 }
18013 return;
18014 }
18015
18016 case value_t::number_integer:
18017 {
18018 dump_integer(val.m_value.number_integer);
18019 return;
18020 }
18021
18022 case value_t::number_unsigned:
18023 {
18024 dump_integer(val.m_value.number_unsigned);
18025 return;
18026 }
18027
18028 case value_t::number_float:
18029 {
18030 dump_float(val.m_value.number_float);
18031 return;
18032 }
18033
18034 case value_t::discarded:
18035 {
18036 o->write_characters("<discarded>", 11);
18037 return;
18038 }
18039
18040 case value_t::null:
18041 {
18042 o->write_characters("null", 4);
18043 return;
18044 }
18045
18046 default: // LCOV_EXCL_LINE
18047 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18048 }
18049 }
18050
18066 void dump_escaped(const string_t& s, const bool ensure_ascii)
18067 {
18068 std::uint32_t codepoint{};
18069 std::uint8_t state = UTF8_ACCEPT;
18070 std::size_t bytes = 0; // number of bytes written to string_buffer
18071
18072 // number of bytes written at the point of the last valid byte
18073 std::size_t bytes_after_last_accept = 0;
18074 std::size_t undumped_chars = 0;
18075
18076 for (std::size_t i = 0; i < s.size(); ++i)
18077 {
18078 const auto byte = static_cast<std::uint8_t>(s[i]);
18079
18080 switch (decode(state, codepoint, byte))
18081 {
18082 case UTF8_ACCEPT: // decode found a new code point
18083 {
18084 switch (codepoint)
18085 {
18086 case 0x08: // backspace
18087 {
18088 string_buffer[bytes++] = '\\';
18089 string_buffer[bytes++] = 'b';
18090 break;
18091 }
18092
18093 case 0x09: // horizontal tab
18094 {
18095 string_buffer[bytes++] = '\\';
18096 string_buffer[bytes++] = 't';
18097 break;
18098 }
18099
18100 case 0x0A: // newline
18101 {
18102 string_buffer[bytes++] = '\\';
18103 string_buffer[bytes++] = 'n';
18104 break;
18105 }
18106
18107 case 0x0C: // formfeed
18108 {
18109 string_buffer[bytes++] = '\\';
18110 string_buffer[bytes++] = 'f';
18111 break;
18112 }
18113
18114 case 0x0D: // carriage return
18115 {
18116 string_buffer[bytes++] = '\\';
18117 string_buffer[bytes++] = 'r';
18118 break;
18119 }
18120
18121 case 0x22: // quotation mark
18122 {
18123 string_buffer[bytes++] = '\\';
18124 string_buffer[bytes++] = '\"';
18125 break;
18126 }
18127
18128 case 0x5C: // reverse solidus
18129 {
18130 string_buffer[bytes++] = '\\';
18131 string_buffer[bytes++] = '\\';
18132 break;
18133 }
18134
18135 default:
18136 {
18137 // escape control characters (0x00..0x1F) or, if
18138 // ensure_ascii parameter is used, non-ASCII characters
18139 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
18140 {
18141 if (codepoint <= 0xFFFF)
18142 {
18143 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18144 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
18145 static_cast<std::uint16_t>(codepoint)));
18146 bytes += 6;
18147 }
18148 else
18149 {
18150 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18151 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
18152 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
18153 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
18154 bytes += 12;
18155 }
18156 }
18157 else
18158 {
18159 // copy byte to buffer (all previous bytes
18160 // been copied have in default case above)
18161 string_buffer[bytes++] = s[i];
18162 }
18163 break;
18164 }
18165 }
18166
18167 // write buffer and reset index; there must be 13 bytes
18168 // left, as this is the maximal number of bytes to be
18169 // written ("\uxxxx\uxxxx\0") for one code point
18170 if (string_buffer.size() - bytes < 13)
18171 {
18172 o->write_characters(string_buffer.data(), bytes);
18173 bytes = 0;
18174 }
18175
18176 // remember the byte position of this accept
18177 bytes_after_last_accept = bytes;
18178 undumped_chars = 0;
18179 break;
18180 }
18181
18182 case UTF8_REJECT: // decode found invalid UTF-8 byte
18183 {
18184 switch (error_handler)
18185 {
18186 case error_handler_t::strict:
18187 {
18188 JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
18189 }
18190
18191 case error_handler_t::ignore:
18192 case error_handler_t::replace:
18193 {
18194 // in case we saw this character the first time, we
18195 // would like to read it again, because the byte
18196 // may be OK for itself, but just not OK for the
18197 // previous sequence
18198 if (undumped_chars > 0)
18199 {
18200 --i;
18201 }
18202
18203 // reset length buffer to the last accepted index;
18204 // thus removing/ignoring the invalid characters
18205 bytes = bytes_after_last_accept;
18206
18207 if (error_handler == error_handler_t::replace)
18208 {
18209 // add a replacement character
18210 if (ensure_ascii)
18211 {
18212 string_buffer[bytes++] = '\\';
18213 string_buffer[bytes++] = 'u';
18214 string_buffer[bytes++] = 'f';
18215 string_buffer[bytes++] = 'f';
18216 string_buffer[bytes++] = 'f';
18217 string_buffer[bytes++] = 'd';
18218 }
18219 else
18220 {
18221 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
18222 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
18223 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
18224 }
18225
18226 // write buffer and reset index; there must be 13 bytes
18227 // left, as this is the maximal number of bytes to be
18228 // written ("\uxxxx\uxxxx\0") for one code point
18229 if (string_buffer.size() - bytes < 13)
18230 {
18231 o->write_characters(string_buffer.data(), bytes);
18232 bytes = 0;
18233 }
18234
18235 bytes_after_last_accept = bytes;
18236 }
18237
18238 undumped_chars = 0;
18239
18240 // continue processing the string
18241 state = UTF8_ACCEPT;
18242 break;
18243 }
18244
18245 default: // LCOV_EXCL_LINE
18246 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18247 }
18248 break;
18249 }
18250
18251 default: // decode found yet incomplete multi-byte code point
18252 {
18253 if (!ensure_ascii)
18254 {
18255 // code point will not be escaped - copy byte to buffer
18256 string_buffer[bytes++] = s[i];
18257 }
18258 ++undumped_chars;
18259 break;
18260 }
18261 }
18262 }
18263
18264 // we finished processing the string
18265 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
18266 {
18267 // write buffer
18268 if (bytes > 0)
18269 {
18270 o->write_characters(string_buffer.data(), bytes);
18271 }
18272 }
18273 else
18274 {
18275 // we finish reading, but do not accept: string was incomplete
18276 switch (error_handler)
18277 {
18278 case error_handler_t::strict:
18279 {
18280 JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
18281 }
18282
18283 case error_handler_t::ignore:
18284 {
18285 // write all accepted bytes
18286 o->write_characters(string_buffer.data(), bytes_after_last_accept);
18287 break;
18288 }
18289
18290 case error_handler_t::replace:
18291 {
18292 // write all accepted bytes
18293 o->write_characters(string_buffer.data(), bytes_after_last_accept);
18294 // add a replacement character
18295 if (ensure_ascii)
18296 {
18297 o->write_characters("\\ufffd", 6);
18298 }
18299 else
18300 {
18301 o->write_characters("\xEF\xBF\xBD", 3);
18302 }
18303 break;
18304 }
18305
18306 default: // LCOV_EXCL_LINE
18307 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18308 }
18309 }
18310 }
18311
18312 private:
18321 inline unsigned int count_digits(number_unsigned_t x) noexcept
18322 {
18323 unsigned int n_digits = 1;
18324 for (;;)
18325 {
18326 if (x < 10)
18327 {
18328 return n_digits;
18329 }
18330 if (x < 100)
18331 {
18332 return n_digits + 1;
18333 }
18334 if (x < 1000)
18335 {
18336 return n_digits + 2;
18337 }
18338 if (x < 10000)
18339 {
18340 return n_digits + 3;
18341 }
18342 x = x / 10000u;
18343 n_digits += 4;
18344 }
18345 }
18346
18352 static std::string hex_bytes(std::uint8_t byte)
18353 {
18354 std::string result = "FF";
18355 constexpr const char* nibble_to_hex = "0123456789ABCDEF";
18356 result[0] = nibble_to_hex[byte / 16];
18357 result[1] = nibble_to_hex[byte % 16];
18358 return result;
18359 }
18360
18361 // templates to avoid warnings about useless casts
18362 template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
18363 bool is_negative_number(NumberType x)
18364 {
18365 return x < 0;
18366 }
18367
18368 template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
18369 bool is_negative_number(NumberType /*unused*/)
18370 {
18371 return false;
18372 }
18373
18383 template < typename NumberType, detail::enable_if_t <
18384 std::is_integral<NumberType>::value ||
18385 std::is_same<NumberType, number_unsigned_t>::value ||
18386 std::is_same<NumberType, number_integer_t>::value ||
18387 std::is_same<NumberType, binary_char_t>::value,
18388 int > = 0 >
18389 void dump_integer(NumberType x)
18390 {
18391 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
18392 {
18393 {
18394 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
18395 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
18396 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
18397 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
18398 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
18399 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
18400 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
18401 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
18402 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
18403 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
18404 }
18405 };
18406
18407 // special case for "0"
18408 if (x == 0)
18409 {
18410 o->write_character('0');
18411 return;
18412 }
18413
18414 // use a pointer to fill the buffer
18415 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18416
18417 number_unsigned_t abs_value;
18418
18419 unsigned int n_chars{};
18420
18421 if (is_negative_number(x))
18422 {
18423 *buffer_ptr = '-';
18424 abs_value = remove_sign(static_cast<number_integer_t>(x));
18425
18426 // account one more byte for the minus sign
18427 n_chars = 1 + count_digits(abs_value);
18428 }
18429 else
18430 {
18431 abs_value = static_cast<number_unsigned_t>(x);
18432 n_chars = count_digits(abs_value);
18433 }
18434
18435 // spare 1 byte for '\0'
18436 JSON_ASSERT(n_chars < number_buffer.size() - 1);
18437
18438 // jump to the end to generate the string from backward,
18439 // so we later avoid reversing the result
18440 buffer_ptr += n_chars;
18441
18442 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18443 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18444 while (abs_value >= 100)
18445 {
18446 const auto digits_index = static_cast<unsigned>((abs_value % 100));
18447 abs_value /= 100;
18448 *(--buffer_ptr) = digits_to_99[digits_index][1];
18449 *(--buffer_ptr) = digits_to_99[digits_index][0];
18450 }
18451
18452 if (abs_value >= 10)
18453 {
18454 const auto digits_index = static_cast<unsigned>(abs_value);
18455 *(--buffer_ptr) = digits_to_99[digits_index][1];
18456 *(--buffer_ptr) = digits_to_99[digits_index][0];
18457 }
18458 else
18459 {
18460 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18461 }
18462
18463 o->write_characters(number_buffer.data(), n_chars);
18464 }
18465
18474 void dump_float(number_float_t x)
18475 {
18476 // NaN / inf
18477 if (!std::isfinite(x))
18478 {
18479 o->write_characters("null", 4);
18480 return;
18481 }
18482
18483 // If number_float_t is an IEEE-754 single or double precision number,
18484 // use the Grisu2 algorithm to produce short numbers which are
18485 // guaranteed to round-trip, using strtof and strtod, resp.
18486 //
18487 // NB: The test below works if <long double> == <double>.
18488 static constexpr bool is_ieee_single_or_double
18489 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
18490 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
18491
18492 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18493 }
18494
18495 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18496 {
18497 auto* begin = number_buffer.data();
18498 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18499
18500 o->write_characters(begin, static_cast<size_t>(end - begin));
18501 }
18502
18503 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18504 {
18505 // get number of digits for a float -> text -> float round-trip
18506 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18507
18508 // the actual conversion
18509 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18510 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18511
18512 // negative value indicates an error
18513 JSON_ASSERT(len > 0);
18514 // check if buffer was large enough
18515 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18516
18517 // erase thousands separator
18518 if (thousands_sep != '\0')
18519 {
18520 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18521 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18522 std::fill(end, number_buffer.end(), '\0');
18523 JSON_ASSERT((end - number_buffer.begin()) <= len);
18524 len = (end - number_buffer.begin());
18525 }
18526
18527 // convert decimal point to '.'
18528 if (decimal_point != '\0' && decimal_point != '.')
18529 {
18530 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18531 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18532 if (dec_pos != number_buffer.end())
18533 {
18534 *dec_pos = '.';
18535 }
18536 }
18537
18538 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18539
18540 // determine if we need to append ".0"
18541 const bool value_is_int_like =
18542 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18543 [](char c)
18544 {
18545 return c == '.' || c == 'e';
18546 });
18547
18548 if (value_is_int_like)
18549 {
18550 o->write_characters(".0", 2);
18551 }
18552 }
18553
18575 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18576 {
18577 static const std::array<std::uint8_t, 400> utf8d =
18578 {
18579 {
18580 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
18581 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
18582 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
18583 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
18584 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
18585 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
18586 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
18587 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18588 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18589 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18590 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
18591 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
18592 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
18593 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
18594 }
18595 };
18596
18597 JSON_ASSERT(byte < utf8d.size());
18598 const std::uint8_t type = utf8d[byte];
18599
18600 codep = (state != UTF8_ACCEPT)
18601 ? (byte & 0x3fu) | (codep << 6u)
18602 : (0xFFu >> type) & (byte);
18603
18604 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18605 JSON_ASSERT(index < 400);
18606 state = utf8d[index];
18607 return state;
18608 }
18609
18610 /*
18611 * Overload to make the compiler happy while it is instantiating
18612 * dump_integer for number_unsigned_t.
18613 * Must never be called.
18614 */
18616 {
18617 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18618 return x; // LCOV_EXCL_LINE
18619 }
18620
18621 /*
18622 * Helper function for dump_integer
18623 *
18624 * This function takes a negative signed integer and returns its absolute
18625 * value as unsigned integer. The plus/minus shuffling is necessary as we can
18626 * not directly remove the sign of an arbitrary signed integer as the
18627 * absolute values of INT_MIN and INT_MAX are usually not the same. See
18628 * #1708 for details.
18629 */
18630 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18631 {
18632 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18633 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18634 }
18635
18636 private:
18638 output_adapter_t<char> o = nullptr;
18639
18641 std::array<char, 64> number_buffer{{}};
18642
18644 const std::lconv* loc = nullptr;
18646 const char thousands_sep = '\0';
18648 const char decimal_point = '\0';
18649
18651 std::array<char, 512> string_buffer{{}};
18652
18654 const char indent_char;
18657
18660};
18661
18662} // namespace detail
18664
18665// #include <nlohmann/detail/value_t.hpp>
18666
18667// #include <nlohmann/json_fwd.hpp>
18668
18669// #include <nlohmann/ordered_map.hpp>
18670// __ _____ _____ _____
18671// __| | __| | | | JSON for Modern C++
18672// | | |__ | | | | | | version 3.11.1
18673// |_____|_____|_____|_|___| https://github.com/nlohmann/json
18674//
18675// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
18676// SPDX-License-Identifier: MIT
18677
18678
18679
18680#include <functional> // equal_to, less
18681#include <initializer_list> // initializer_list
18682#include <iterator> // input_iterator_tag, iterator_traits
18683#include <memory> // allocator
18684#include <stdexcept> // for out_of_range
18685#include <type_traits> // enable_if, is_convertible
18686#include <utility> // pair
18687#include <vector> // vector
18688
18689// #include <nlohmann/detail/macro_scope.hpp>
18690
18691// #include <nlohmann/detail/meta/type_traits.hpp>
18692
18693
18695
18698template <class Key, class T, class IgnoredLess = std::less<Key>,
18699 class Allocator = std::allocator<std::pair<const Key, T>>>
18700 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
18701{
18702 using key_type = Key;
18703 using mapped_type = T;
18704 using Container = std::vector<std::pair<const Key, T>, Allocator>;
18705 using iterator = typename Container::iterator;
18706 using const_iterator = typename Container::const_iterator;
18707 using size_type = typename Container::size_type;
18708 using value_type = typename Container::value_type;
18709#ifdef JSON_HAS_CPP_14
18710 using key_compare = std::equal_to<>;
18711#else
18712 using key_compare = std::equal_to<Key>;
18713#endif
18714
18715 // Explicit constructors instead of `using Container::Container`
18716 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
18717 ordered_map() noexcept(noexcept(Container())) : Container{} {}
18718 explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
18719 template <class It>
18720 ordered_map(It first, It last, const Allocator& alloc = Allocator())
18721 : Container{first, last, alloc} {}
18722 ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
18723 : Container{init, alloc} {}
18724
18725 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
18726 {
18727 for (auto it = this->begin(); it != this->end(); ++it)
18728 {
18729 if (m_compare(it->first, key))
18730 {
18731 return {it, false};
18732 }
18733 }
18734 Container::emplace_back(key, std::forward<T>(t));
18735 return {std::prev(this->end()), true};
18736 }
18737
18738 template<class KeyType, detail::enable_if_t<
18740 std::pair<iterator, bool> emplace(KeyType && key, T && t)
18741 {
18742 for (auto it = this->begin(); it != this->end(); ++it)
18743 {
18744 if (m_compare(it->first, key))
18745 {
18746 return {it, false};
18747 }
18748 }
18749 Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
18750 return {std::prev(this->end()), true};
18751 }
18752
18754 {
18755 return emplace(key, T{}).first->second;
18756 }
18757
18758 template<class KeyType, detail::enable_if_t<
18760 T & operator[](KeyType && key)
18761 {
18762 return emplace(std::forward<KeyType>(key), T{}).first->second;
18763 }
18764
18765 const T& operator[](const key_type& key) const
18766 {
18767 return at(key);
18768 }
18769
18770 template<class KeyType, detail::enable_if_t<
18772 const T & operator[](KeyType && key) const
18773 {
18774 return at(std::forward<KeyType>(key));
18775 }
18776
18777 T& at(const key_type& key)
18778 {
18779 for (auto it = this->begin(); it != this->end(); ++it)
18780 {
18781 if (m_compare(it->first, key))
18782 {
18783 return it->second;
18784 }
18785 }
18786
18787 JSON_THROW(std::out_of_range("key not found"));
18788 }
18789
18790 template<class KeyType, detail::enable_if_t<
18792 T & at(KeyType && key)
18793 {
18794 for (auto it = this->begin(); it != this->end(); ++it)
18795 {
18796 if (m_compare(it->first, key))
18797 {
18798 return it->second;
18799 }
18800 }
18801
18802 JSON_THROW(std::out_of_range("key not found"));
18803 }
18804
18805 const T& at(const key_type& key) const
18806 {
18807 for (auto it = this->begin(); it != this->end(); ++it)
18808 {
18809 if (m_compare(it->first, key))
18810 {
18811 return it->second;
18812 }
18813 }
18814
18815 JSON_THROW(std::out_of_range("key not found"));
18816 }
18817
18818 template<class KeyType, detail::enable_if_t<
18820 const T & at(KeyType && key) const
18821 {
18822 for (auto it = this->begin(); it != this->end(); ++it)
18823 {
18824 if (m_compare(it->first, key))
18825 {
18826 return it->second;
18827 }
18828 }
18829
18830 JSON_THROW(std::out_of_range("key not found"));
18831 }
18832
18834 {
18835 for (auto it = this->begin(); it != this->end(); ++it)
18836 {
18837 if (m_compare(it->first, key))
18838 {
18839 // Since we cannot move const Keys, re-construct them in place
18840 for (auto next = it; ++next != this->end(); ++it)
18841 {
18842 it->~value_type(); // Destroy but keep allocation
18843 new (&*it) value_type{std::move(*next)};
18844 }
18845 Container::pop_back();
18846 return 1;
18847 }
18848 }
18849 return 0;
18850 }
18851
18852 template<class KeyType, detail::enable_if_t<
18854 size_type erase(KeyType && key)
18855 {
18856 for (auto it = this->begin(); it != this->end(); ++it)
18857 {
18858 if (m_compare(it->first, key))
18859 {
18860 // Since we cannot move const Keys, re-construct them in place
18861 for (auto next = it; ++next != this->end(); ++it)
18862 {
18863 it->~value_type(); // Destroy but keep allocation
18864 new (&*it) value_type{std::move(*next)};
18865 }
18866 Container::pop_back();
18867 return 1;
18868 }
18869 }
18870 return 0;
18871 }
18872
18874 {
18875 return erase(pos, std::next(pos));
18876 }
18877
18879 {
18880 if (first == last)
18881 {
18882 return first;
18883 }
18884
18885 const auto elements_affected = std::distance(first, last);
18886 const auto offset = std::distance(Container::begin(), first);
18887
18888 // This is the start situation. We need to delete elements_affected
18889 // elements (3 in this example: e, f, g), and need to return an
18890 // iterator past the last deleted element (h in this example).
18891 // Note that offset is the distance from the start of the vector
18892 // to first. We will need this later.
18893
18894 // [ a, b, c, d, e, f, g, h, i, j ]
18895 // ^ ^
18896 // first last
18897
18898 // Since we cannot move const Keys, we re-construct them in place.
18899 // We start at first and re-construct (viz. copy) the elements from
18900 // the back of the vector. Example for first iteration:
18901
18902 // ,--------.
18903 // v | destroy e and re-construct with h
18904 // [ a, b, c, d, e, f, g, h, i, j ]
18905 // ^ ^
18906 // it it + elements_affected
18907
18908 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
18909 {
18910 it->~value_type(); // destroy but keep allocation
18911 new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
18912 }
18913
18914 // [ a, b, c, d, h, i, j, h, i, j ]
18915 // ^ ^
18916 // first last
18917
18918 // remove the unneeded elements at the end of the vector
18919 Container::resize(this->size() - static_cast<size_type>(elements_affected));
18920
18921 // [ a, b, c, d, h, i, j ]
18922 // ^ ^
18923 // first last
18924
18925 // first is now pointing past the last deleted element, but we cannot
18926 // use this iterator, because it may have been invalidated by the
18927 // resize call. Instead, we can return begin() + offset.
18928 return Container::begin() + offset;
18929 }
18930
18932 {
18933 for (auto it = this->begin(); it != this->end(); ++it)
18934 {
18935 if (m_compare(it->first, key))
18936 {
18937 return 1;
18938 }
18939 }
18940 return 0;
18941 }
18942
18943 template<class KeyType, detail::enable_if_t<
18945 size_type count(KeyType && key) const
18946 {
18947 for (auto it = this->begin(); it != this->end(); ++it)
18948 {
18949 if (m_compare(it->first, key))
18950 {
18951 return 1;
18952 }
18953 }
18954 return 0;
18955 }
18956
18958 {
18959 for (auto it = this->begin(); it != this->end(); ++it)
18960 {
18961 if (m_compare(it->first, key))
18962 {
18963 return it;
18964 }
18965 }
18966 return Container::end();
18967 }
18968
18969 template<class KeyType, detail::enable_if_t<
18971 iterator find(KeyType && key)
18972 {
18973 for (auto it = this->begin(); it != this->end(); ++it)
18974 {
18975 if (m_compare(it->first, key))
18976 {
18977 return it;
18978 }
18979 }
18980 return Container::end();
18981 }
18982
18984 {
18985 for (auto it = this->begin(); it != this->end(); ++it)
18986 {
18987 if (m_compare(it->first, key))
18988 {
18989 return it;
18990 }
18991 }
18992 return Container::end();
18993 }
18994
18995 std::pair<iterator, bool> insert( value_type&& value )
18996 {
18997 return emplace(value.first, std::move(value.second));
18998 }
18999
19000 std::pair<iterator, bool> insert( const value_type& value )
19001 {
19002 for (auto it = this->begin(); it != this->end(); ++it)
19003 {
19004 if (m_compare(it->first, value.first))
19005 {
19006 return {it, false};
19007 }
19008 }
19009 Container::push_back(value);
19010 return {--this->end(), true};
19011 }
19012
19013 template<typename InputIt>
19014 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
19015 std::input_iterator_tag>::value>::type;
19016
19017 template<typename InputIt, typename = require_input_iter<InputIt>>
19018 void insert(InputIt first, InputIt last)
19019 {
19020 for (auto it = first; it != last; ++it)
19021 {
19022 insert(*it);
19023 }
19024 }
19025
19026private:
19028};
19029
19031
19032
19033#if defined(JSON_HAS_CPP_17)
19034 #include <any>
19035 #include <string_view>
19036#endif
19037
19044
19064class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
19065{
19066 private:
19067 template<detail::value_t> friend struct detail::external_constructor;
19068
19069 template<typename>
19070 friend class ::nlohmann::json_pointer;
19071 // can be restored when json_pointer backwards compatibility is removed
19072 // friend ::nlohmann::json_pointer<StringType>;
19073
19074 template<typename BasicJsonType, typename InputType>
19075 friend class ::nlohmann::detail::parser;
19076 friend ::nlohmann::detail::serializer<basic_json>;
19077 template<typename BasicJsonType>
19078 friend class ::nlohmann::detail::iter_impl;
19079 template<typename BasicJsonType, typename CharType>
19080 friend class ::nlohmann::detail::binary_writer;
19081 template<typename BasicJsonType, typename InputType, typename SAX>
19082 friend class ::nlohmann::detail::binary_reader;
19083 template<typename BasicJsonType>
19084 friend class ::nlohmann::detail::json_sax_dom_parser;
19085 template<typename BasicJsonType>
19086 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
19087 friend class ::nlohmann::detail::exception;
19088
19091
19093 // convenience aliases for types residing in namespace detail;
19094 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
19095
19096 template<typename InputAdapterType>
19097 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
19098 InputAdapterType adapter,
19100 const bool allow_exceptions = true,
19101 const bool ignore_comments = false
19102 )
19103 {
19104 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
19105 std::move(cb), allow_exceptions, ignore_comments);
19106 }
19107
19108 private:
19109 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
19110 template<typename BasicJsonType>
19111 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
19112 template<typename BasicJsonType>
19113 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
19114 template<typename Iterator>
19115 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
19116 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
19117
19118 template<typename CharType>
19119 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
19120
19121 template<typename InputType>
19122 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
19123 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
19124
19126 using serializer = ::nlohmann::detail::serializer<basic_json>;
19127
19128 public:
19131 using json_pointer = ::nlohmann::json_pointer<StringType>;
19132 template<typename T, typename SFINAE>
19133 using json_serializer = JSONSerializer<T, SFINAE>;
19139 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19140
19144
19146 // exceptions //
19148
19152
19159
19161
19162
19164 // container types //
19166
19171
19174
19179
19181 using difference_type = std::ptrdiff_t;
19183 using size_type = std::size_t;
19184
19186 using allocator_type = AllocatorType<basic_json>;
19187
19189 using pointer = typename std::allocator_traits<allocator_type>::pointer;
19191 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19192
19201
19203
19204
19208 {
19209 return allocator_type();
19210 }
19211
19216 {
19217 basic_json result;
19218
19219 result["copyright"] = "(C) 2013-2022 Niels Lohmann";
19220 result["name"] = "JSON for Modern C++";
19221 result["url"] = "https://github.com/nlohmann/json";
19222 result["version"]["string"] =
19226 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
19227 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
19228 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
19229
19230#ifdef _WIN32
19231 result["platform"] = "win32";
19232#elif defined __linux__
19233 result["platform"] = "linux";
19234#elif defined __APPLE__
19235 result["platform"] = "apple";
19236#elif defined __unix__
19237 result["platform"] = "unix";
19238#else
19239 result["platform"] = "unknown";
19240#endif
19241
19242#if defined(__ICC) || defined(__INTEL_COMPILER)
19243 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
19244#elif defined(__clang__)
19245 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
19246#elif defined(__GNUC__) || defined(__GNUG__)
19247 result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
19248 std::to_string(__GNUC__), '.',
19249 std::to_string(__GNUC_MINOR__), '.',
19250 std::to_string(__GNUC_PATCHLEVEL__))
19251 }
19252 };
19253#elif defined(__HP_cc) || defined(__HP_aCC)
19254 result["compiler"] = "hp"
19255#elif defined(__IBMCPP__)
19256 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
19257#elif defined(_MSC_VER)
19258 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
19259#elif defined(__PGI)
19260 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
19261#elif defined(__SUNPRO_CC)
19262 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
19263#else
19264 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
19265#endif
19266
19267
19268#if defined(_MSVC_LANG)
19269 result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
19270#elif defined(__cplusplus)
19271 result["compiler"]["c++"] = std::to_string(__cplusplus);
19272#else
19273 result["compiler"]["c++"] = "unknown";
19274#endif
19275 return result;
19276 }
19277
19278
19280 // JSON value data types //
19282
19287
19292#if defined(JSON_HAS_CPP_14)
19293 // use of transparent comparator avoids unnecessary repeated construction of temporaries
19294 // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
19295 using default_object_comparator_t = std::less<>;
19296#else
19297 using default_object_comparator_t = std::less<StringType>;
19298#endif
19299
19302 using object_t = ObjectType<StringType,
19303 basic_json,
19305 AllocatorType<std::pair<const StringType,
19306 basic_json>>>;
19307
19310 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19311
19314 using string_t = StringType;
19315
19318 using boolean_t = BooleanType;
19319
19322 using number_integer_t = NumberIntegerType;
19323
19326 using number_unsigned_t = NumberUnsignedType;
19327
19330 using number_float_t = NumberFloatType;
19331
19334 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19335
19339
19341
19342 private:
19343
19345 template<typename T, typename... Args>
19347 static T* create(Args&& ... args)
19348 {
19349 AllocatorType<T> alloc;
19350 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
19351
19352 auto deleter = [&](T * obj)
19353 {
19354 AllocatorTraits::deallocate(alloc, obj, 1);
19355 };
19356 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
19357 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
19358 JSON_ASSERT(obj != nullptr);
19359 return obj.release();
19360 }
19361
19363 // JSON value storage //
19365
19392 union json_value
19393 {
19395 object_t* object;
19410
19412 json_value() = default;
19414 json_value(boolean_t v) noexcept : boolean(v) {}
19423 {
19424 switch (t)
19425 {
19426 case value_t::object:
19427 {
19428 object = create<object_t>();
19429 break;
19430 }
19431
19432 case value_t::array:
19433 {
19434 array = create<array_t>();
19435 break;
19436 }
19437
19438 case value_t::string:
19439 {
19440 string = create<string_t>("");
19441 break;
19442 }
19443
19444 case value_t::binary:
19445 {
19446 binary = create<binary_t>();
19447 break;
19448 }
19449
19450 case value_t::boolean:
19451 {
19452 boolean = static_cast<boolean_t>(false);
19453 break;
19454 }
19455
19456 case value_t::number_integer:
19457 {
19458 number_integer = static_cast<number_integer_t>(0);
19459 break;
19460 }
19461
19462 case value_t::number_unsigned:
19463 {
19464 number_unsigned = static_cast<number_unsigned_t>(0);
19465 break;
19466 }
19467
19468 case value_t::number_float:
19469 {
19470 number_float = static_cast<number_float_t>(0.0);
19471 break;
19472 }
19473
19474 case value_t::null:
19475 {
19476 object = nullptr; // silence warning, see #821
19477 break;
19478 }
19479
19480 case value_t::discarded:
19481 default:
19482 {
19483 object = nullptr; // silence warning, see #821
19484 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
19485 {
19486 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.1", nullptr)); // LCOV_EXCL_LINE
19487 }
19488 break;
19489 }
19490 }
19491 }
19492
19494 json_value(const string_t& value) : string(create<string_t>(value)) {}
19495
19497 json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19498
19500 json_value(const object_t& value) : object(create<object_t>(value)) {}
19501
19503 json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19504
19506 json_value(const array_t& value) : array(create<array_t>(value)) {}
19507
19509 json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19510
19512 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19513
19515 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19516
19518 json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
19519
19521 json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
19522
19524 {
19525 if (t == value_t::array || t == value_t::object)
19526 {
19527 // flatten the current json_value to a heap-allocated stack
19528 std::vector<basic_json> stack;
19529
19530 // move the top-level items to stack
19531 if (t == value_t::array)
19532 {
19533 stack.reserve(array->size());
19534 std::move(array->begin(), array->end(), std::back_inserter(stack));
19535 }
19536 else
19537 {
19538 stack.reserve(object->size());
19539 for (auto&& it : *object)
19540 {
19541 stack.push_back(std::move(it.second));
19542 }
19543 }
19544
19545 while (!stack.empty())
19546 {
19547 // move the last item to local variable to be processed
19548 basic_json current_item(std::move(stack.back()));
19549 stack.pop_back();
19550
19551 // if current_item is array/object, move
19552 // its children to the stack to be processed later
19553 if (current_item.is_array())
19554 {
19555 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
19556
19557 current_item.m_value.array->clear();
19558 }
19559 else if (current_item.is_object())
19560 {
19561 for (auto&& it : *current_item.m_value.object)
19562 {
19563 stack.push_back(std::move(it.second));
19564 }
19565
19566 current_item.m_value.object->clear();
19567 }
19568
19569 // it's now safe that current_item get destructed
19570 // since it doesn't have any children
19571 }
19572 }
19573
19574 switch (t)
19575 {
19576 case value_t::object:
19577 {
19578 AllocatorType<object_t> alloc;
19579 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19580 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19581 break;
19582 }
19583
19584 case value_t::array:
19585 {
19586 AllocatorType<array_t> alloc;
19587 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19588 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19589 break;
19590 }
19591
19592 case value_t::string:
19593 {
19594 AllocatorType<string_t> alloc;
19595 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19596 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19597 break;
19598 }
19599
19600 case value_t::binary:
19601 {
19602 AllocatorType<binary_t> alloc;
19603 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19604 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19605 break;
19606 }
19607
19608 case value_t::null:
19609 case value_t::boolean:
19610 case value_t::number_integer:
19611 case value_t::number_unsigned:
19612 case value_t::number_float:
19613 case value_t::discarded:
19614 default:
19615 {
19616 break;
19617 }
19618 }
19619 }
19620 };
19621
19622 private:
19641 void assert_invariant(bool check_parents = true) const noexcept
19642 {
19643 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
19644 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
19645 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
19646 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
19647
19648#if JSON_DIAGNOSTICS
19649 JSON_TRY
19650 {
19651 // cppcheck-suppress assertWithSideEffect
19652 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
19653 {
19654 return j.m_parent == this;
19655 }));
19656 }
19657 JSON_CATCH(...) {} // LCOV_EXCL_LINE
19658#endif
19659 static_cast<void>(check_parents);
19660 }
19661
19663 {
19664#if JSON_DIAGNOSTICS
19665 switch (m_type)
19666 {
19667 case value_t::array:
19668 {
19669 for (auto& element : *m_value.array)
19670 {
19671 element.m_parent = this;
19672 }
19673 break;
19674 }
19675
19676 case value_t::object:
19677 {
19678 for (auto& element : *m_value.object)
19679 {
19680 element.second.m_parent = this;
19681 }
19682 break;
19683 }
19684
19685 case value_t::null:
19686 case value_t::string:
19687 case value_t::boolean:
19688 case value_t::number_integer:
19689 case value_t::number_unsigned:
19690 case value_t::number_float:
19691 case value_t::binary:
19692 case value_t::discarded:
19693 default:
19694 break;
19695 }
19696#endif
19697 }
19698
19699 iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
19700 {
19701#if JSON_DIAGNOSTICS
19702 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
19703 {
19704 (it + i)->m_parent = this;
19705 }
19706#else
19707 static_cast<void>(count_set_parents);
19708#endif
19709 return it;
19710 }
19711
19712 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
19713 {
19714#if JSON_DIAGNOSTICS
19715 if (old_capacity != static_cast<std::size_t>(-1))
19716 {
19717 // see https://github.com/nlohmann/json/issues/2838
19718 JSON_ASSERT(type() == value_t::array);
19719 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
19720 {
19721 // capacity has changed: update all parents
19722 set_parents();
19723 return j;
19724 }
19725 }
19726
19727 // ordered_json uses a vector internally, so pointers could have
19728 // been invalidated; see https://github.com/nlohmann/json/issues/2962
19729#ifdef JSON_HEDLEY_MSVC_VERSION
19730#pragma warning(push )
19731#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
19732#endif
19734 {
19735 set_parents();
19736 return j;
19737 }
19738#ifdef JSON_HEDLEY_MSVC_VERSION
19739#pragma warning( pop )
19740#endif
19741
19742 j.m_parent = this;
19743#else
19744 static_cast<void>(j);
19745 static_cast<void>(old_capacity);
19746#endif
19747 return j;
19748 }
19749
19750 public:
19752 // JSON parser callback //
19754
19758
19762
19764 // constructors //
19766
19771
19775 : m_type(v), m_value(v)
19776 {
19777 assert_invariant();
19778 }
19779
19782 basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
19784 {
19785 assert_invariant();
19786 }
19787
19790 template < typename CompatibleType,
19794 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19795 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
19796 std::forward<CompatibleType>(val))))
19797 {
19798 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19799 set_parents();
19800 assert_invariant();
19801 }
19802
19805 template < typename BasicJsonType,
19807 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19808 basic_json(const BasicJsonType& val)
19809 {
19810 using other_boolean_t = typename BasicJsonType::boolean_t;
19811 using other_number_float_t = typename BasicJsonType::number_float_t;
19812 using other_number_integer_t = typename BasicJsonType::number_integer_t;
19813 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19814 using other_string_t = typename BasicJsonType::string_t;
19815 using other_object_t = typename BasicJsonType::object_t;
19816 using other_array_t = typename BasicJsonType::array_t;
19817 using other_binary_t = typename BasicJsonType::binary_t;
19818
19819 switch (val.type())
19820 {
19821 case value_t::boolean:
19822 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19823 break;
19824 case value_t::number_float:
19825 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19826 break;
19827 case value_t::number_integer:
19828 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19829 break;
19830 case value_t::number_unsigned:
19831 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19832 break;
19833 case value_t::string:
19834 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19835 break;
19836 case value_t::object:
19837 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19838 break;
19839 case value_t::array:
19840 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19841 break;
19842 case value_t::binary:
19843 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19844 break;
19845 case value_t::null:
19846 *this = nullptr;
19847 break;
19848 case value_t::discarded:
19849 m_type = value_t::discarded;
19850 break;
19851 default: // LCOV_EXCL_LINE
19852 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19853 }
19854 JSON_ASSERT(m_type == val.type());
19855 set_parents();
19856 assert_invariant();
19857 }
19858
19862 bool type_deduction = true,
19863 value_t manual_type = value_t::array)
19864 {
19865 // check if each element is an array with two elements whose first
19866 // element is a string
19867 bool is_an_object = std::all_of(init.begin(), init.end(),
19868 [](const detail::json_ref<basic_json>& element_ref)
19869 {
19870 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19871 });
19872
19873 // adjust type if type deduction is not wanted
19874 if (!type_deduction)
19875 {
19876 // if array is wanted, do not create an object though possible
19877 if (manual_type == value_t::array)
19878 {
19879 is_an_object = false;
19880 }
19881
19882 // if object is wanted but impossible, throw an exception
19883 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19884 {
19885 JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
19886 }
19887 }
19888
19889 if (is_an_object)
19890 {
19891 // the initializer list is a list of pairs -> create object
19892 m_type = value_t::object;
19893 m_value = value_t::object;
19894
19895 for (auto& element_ref : init)
19896 {
19897 auto element = element_ref.moved_or_copied();
19898 m_value.object->emplace(
19899 std::move(*((*element.m_value.array)[0].m_value.string)),
19900 std::move((*element.m_value.array)[1]));
19901 }
19902 }
19903 else
19904 {
19905 // the initializer list describes an array -> create array
19906 m_type = value_t::array;
19907 m_value.array = create<array_t>(init.begin(), init.end());
19908 }
19909
19910 set_parents();
19911 assert_invariant();
19912 }
19913
19917 static basic_json binary(const typename binary_t::container_type& init)
19918 {
19919 auto res = basic_json();
19920 res.m_type = value_t::binary;
19921 res.m_value = init;
19922 return res;
19923 }
19924
19928 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19929 {
19930 auto res = basic_json();
19931 res.m_type = value_t::binary;
19932 res.m_value = binary_t(init, subtype);
19933 return res;
19934 }
19935
19939 static basic_json binary(typename binary_t::container_type&& init)
19940 {
19941 auto res = basic_json();
19942 res.m_type = value_t::binary;
19943 res.m_value = std::move(init);
19944 return res;
19945 }
19946
19950 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19951 {
19952 auto res = basic_json();
19953 res.m_type = value_t::binary;
19954 res.m_value = binary_t(std::move(init), subtype);
19955 return res;
19956 }
19957
19962 {
19963 return basic_json(init, false, value_t::array);
19964 }
19965
19970 {
19971 return basic_json(init, false, value_t::object);
19972 }
19973
19977 : m_type(value_t::array)
19978 {
19979 m_value.array = create<array_t>(cnt, val);
19980 set_parents();
19981 assert_invariant();
19982 }
19983
19986 template < class InputIT, typename std::enable_if <
19987 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19988 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19989 basic_json(InputIT first, InputIT last)
19990 {
19991 JSON_ASSERT(first.m_object != nullptr);
19992 JSON_ASSERT(last.m_object != nullptr);
19993
19994 // make sure iterator fits the current value
19995 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19996 {
19997 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
19998 }
19999
20000 // copy type from first iterator
20001 m_type = first.m_object->m_type;
20002
20003 // check if iterator range is complete for primitive values
20004 switch (m_type)
20005 {
20006 case value_t::boolean:
20007 case value_t::number_float:
20008 case value_t::number_integer:
20009 case value_t::number_unsigned:
20010 case value_t::string:
20011 {
20012 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
20013 || !last.m_it.primitive_iterator.is_end()))
20014 {
20015 JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
20016 }
20017 break;
20018 }
20019
20020 case value_t::null:
20021 case value_t::object:
20022 case value_t::array:
20023 case value_t::binary:
20024 case value_t::discarded:
20025 default:
20026 break;
20027 }
20028
20029 switch (m_type)
20030 {
20031 case value_t::number_integer:
20032 {
20033 m_value.number_integer = first.m_object->m_value.number_integer;
20034 break;
20035 }
20036
20037 case value_t::number_unsigned:
20038 {
20039 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
20040 break;
20041 }
20042
20043 case value_t::number_float:
20044 {
20045 m_value.number_float = first.m_object->m_value.number_float;
20046 break;
20047 }
20048
20049 case value_t::boolean:
20050 {
20051 m_value.boolean = first.m_object->m_value.boolean;
20052 break;
20053 }
20054
20055 case value_t::string:
20056 {
20057 m_value = *first.m_object->m_value.string;
20058 break;
20059 }
20060
20061 case value_t::object:
20062 {
20063 m_value.object = create<object_t>(first.m_it.object_iterator,
20064 last.m_it.object_iterator);
20065 break;
20066 }
20067
20068 case value_t::array:
20069 {
20070 m_value.array = create<array_t>(first.m_it.array_iterator,
20071 last.m_it.array_iterator);
20072 break;
20073 }
20074
20075 case value_t::binary:
20076 {
20077 m_value = *first.m_object->m_value.binary;
20078 break;
20079 }
20080
20081 case value_t::null:
20082 case value_t::discarded:
20083 default:
20084 JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
20085 }
20086
20087 set_parents();
20088 assert_invariant();
20089 }
20090
20091
20093 // other constructors and destructor //
20095
20096 template<typename JsonRef,
20098 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
20099 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
20100
20104 : m_type(other.m_type)
20105 {
20106 // check of passed value is valid
20107 other.assert_invariant();
20108
20109 switch (m_type)
20110 {
20111 case value_t::object:
20112 {
20113 m_value = *other.m_value.object;
20114 break;
20115 }
20116
20117 case value_t::array:
20118 {
20119 m_value = *other.m_value.array;
20120 break;
20121 }
20122
20123 case value_t::string:
20124 {
20125 m_value = *other.m_value.string;
20126 break;
20127 }
20128
20129 case value_t::boolean:
20130 {
20131 m_value = other.m_value.boolean;
20132 break;
20133 }
20134
20135 case value_t::number_integer:
20136 {
20137 m_value = other.m_value.number_integer;
20138 break;
20139 }
20140
20141 case value_t::number_unsigned:
20142 {
20143 m_value = other.m_value.number_unsigned;
20144 break;
20145 }
20146
20147 case value_t::number_float:
20148 {
20149 m_value = other.m_value.number_float;
20150 break;
20151 }
20152
20153 case value_t::binary:
20154 {
20155 m_value = *other.m_value.binary;
20156 break;
20157 }
20158
20159 case value_t::null:
20160 case value_t::discarded:
20161 default:
20162 break;
20163 }
20164
20165 set_parents();
20166 assert_invariant();
20167 }
20168
20171 basic_json(basic_json&& other) noexcept
20172 : m_type(std::move(other.m_type)),
20173 m_value(std::move(other.m_value))
20174 {
20175 // check that passed value is valid
20176 other.assert_invariant(false);
20177
20178 // invalidate payload
20179 other.m_type = value_t::null;
20180 other.m_value = {};
20181
20182 set_parents();
20183 assert_invariant();
20184 }
20185
20189 std::is_nothrow_move_constructible<value_t>::value&&
20190 std::is_nothrow_move_assignable<value_t>::value&&
20191 std::is_nothrow_move_constructible<json_value>::value&&
20192 std::is_nothrow_move_assignable<json_value>::value
20193 )
20194 {
20195 // check that passed value is valid
20196 other.assert_invariant();
20197
20198 using std::swap;
20199 swap(m_type, other.m_type);
20200 swap(m_value, other.m_value);
20201
20202 set_parents();
20203 assert_invariant();
20204 return *this;
20205 }
20206
20209 ~basic_json() noexcept
20210 {
20211 assert_invariant(false);
20212 m_value.destroy(m_type);
20213 }
20214
20216
20217 public:
20219 // object inspection //
20221
20225
20228 string_t dump(const int indent = -1,
20229 const char indent_char = ' ',
20230 const bool ensure_ascii = false,
20231 const error_handler_t error_handler = error_handler_t::strict) const
20232 {
20233 string_t result;
20234 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20235
20236 if (indent >= 0)
20237 {
20238 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20239 }
20240 else
20241 {
20242 s.dump(*this, false, ensure_ascii, 0);
20243 }
20244
20245 return result;
20246 }
20247
20250 constexpr value_t type() const noexcept
20251 {
20252 return m_type;
20253 }
20254
20257 constexpr bool is_primitive() const noexcept
20258 {
20259 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20260 }
20261
20264 constexpr bool is_structured() const noexcept
20265 {
20266 return is_array() || is_object();
20267 }
20268
20271 constexpr bool is_null() const noexcept
20272 {
20273 return m_type == value_t::null;
20274 }
20275
20278 constexpr bool is_boolean() const noexcept
20279 {
20280 return m_type == value_t::boolean;
20281 }
20282
20285 constexpr bool is_number() const noexcept
20286 {
20287 return is_number_integer() || is_number_float();
20288 }
20289
20292 constexpr bool is_number_integer() const noexcept
20293 {
20294 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20295 }
20296
20299 constexpr bool is_number_unsigned() const noexcept
20300 {
20301 return m_type == value_t::number_unsigned;
20302 }
20303
20306 constexpr bool is_number_float() const noexcept
20307 {
20308 return m_type == value_t::number_float;
20309 }
20310
20313 constexpr bool is_object() const noexcept
20314 {
20315 return m_type == value_t::object;
20316 }
20317
20320 constexpr bool is_array() const noexcept
20321 {
20322 return m_type == value_t::array;
20323 }
20324
20327 constexpr bool is_string() const noexcept
20328 {
20329 return m_type == value_t::string;
20330 }
20331
20334 constexpr bool is_binary() const noexcept
20335 {
20336 return m_type == value_t::binary;
20337 }
20338
20341 constexpr bool is_discarded() const noexcept
20342 {
20343 return m_type == value_t::discarded;
20344 }
20345
20348 constexpr operator value_t() const noexcept
20349 {
20350 return m_type;
20351 }
20352
20354
20355 private:
20357 // value access //
20359
20361 boolean_t get_impl(boolean_t* /*unused*/) const
20362 {
20363 if (JSON_HEDLEY_LIKELY(is_boolean()))
20364 {
20365 return m_value.boolean;
20366 }
20367
20368 JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
20369 }
20370
20372 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20373 {
20374 return is_object() ? m_value.object : nullptr;
20375 }
20376
20378 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20379 {
20380 return is_object() ? m_value.object : nullptr;
20381 }
20382
20384 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20385 {
20386 return is_array() ? m_value.array : nullptr;
20387 }
20388
20390 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20391 {
20392 return is_array() ? m_value.array : nullptr;
20393 }
20394
20396 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20397 {
20398 return is_string() ? m_value.string : nullptr;
20399 }
20400
20402 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20403 {
20404 return is_string() ? m_value.string : nullptr;
20405 }
20406
20408 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20409 {
20410 return is_boolean() ? &m_value.boolean : nullptr;
20411 }
20412
20414 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20415 {
20416 return is_boolean() ? &m_value.boolean : nullptr;
20417 }
20418
20421 {
20422 return is_number_integer() ? &m_value.number_integer : nullptr;
20423 }
20424
20426 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20427 {
20428 return is_number_integer() ? &m_value.number_integer : nullptr;
20429 }
20430
20433 {
20434 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20435 }
20436
20438 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20439 {
20440 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20441 }
20442
20445 {
20446 return is_number_float() ? &m_value.number_float : nullptr;
20447 }
20448
20450 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20451 {
20452 return is_number_float() ? &m_value.number_float : nullptr;
20453 }
20454
20456 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20457 {
20458 return is_binary() ? m_value.binary : nullptr;
20459 }
20460
20462 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20463 {
20464 return is_binary() ? m_value.binary : nullptr;
20465 }
20466
20478 template<typename ReferenceType, typename ThisType>
20479 static ReferenceType get_ref_impl(ThisType& obj)
20480 {
20481 // delegate the call to get_ptr<>()
20482 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20483
20484 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20485 {
20486 return *ptr;
20487 }
20488
20489 JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20490 }
20491
20492 public:
20496
20499 template<typename PointerType, typename std::enable_if<
20500 std::is_pointer<PointerType>::value, int>::type = 0>
20501 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20502 {
20503 // delegate the call to get_impl_ptr<>()
20504 return get_impl_ptr(static_cast<PointerType>(nullptr));
20505 }
20506
20509 template < typename PointerType, typename std::enable_if <
20510 std::is_pointer<PointerType>::value&&
20511 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20512 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20513 {
20514 // delegate the call to get_impl_ptr<>() const
20515 return get_impl_ptr(static_cast<PointerType>(nullptr));
20516 }
20517
20518 private:
20557 template < typename ValueType,
20561 int > = 0 >
20562 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20563 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20564 {
20565 auto ret = ValueType();
20567 return ret;
20568 }
20569
20600 template < typename ValueType,
20603 int > = 0 >
20604 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20605 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20606 {
20608 }
20609
20625 template < typename BasicJsonType,
20628 int > = 0 >
20629 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20630 {
20631 return *this;
20632 }
20633
20648 template<typename BasicJsonType,
20650 std::is_same<BasicJsonType, basic_json_t>::value,
20651 int> = 0>
20653 {
20654 return *this;
20655 }
20656
20661 template<typename PointerType,
20663 std::is_pointer<PointerType>::value,
20664 int> = 0>
20665 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20666 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20667 {
20668 // delegate the call to get_ptr
20669 return get_ptr<PointerType>();
20670 }
20671
20672 public:
20696 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20697#if defined(JSON_HAS_CPP_14)
20698 constexpr
20699#endif
20700 auto get() const noexcept(
20701 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20702 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20703 {
20704 // we cannot static_assert on ValueTypeCV being non-const, because
20705 // there is support for get<const basic_json_t>(), which is why we
20706 // still need the uncvref
20707 static_assert(!std::is_reference<ValueTypeCV>::value,
20708 "get() cannot be used with reference types, you might want to use get_ref()");
20709 return get_impl<ValueType>(detail::priority_tag<4> {});
20710 }
20711
20739 template<typename PointerType, typename std::enable_if<
20740 std::is_pointer<PointerType>::value, int>::type = 0>
20741 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20742 {
20743 // delegate the call to get_ptr
20744 return get_ptr<PointerType>();
20745 }
20746
20749 template < typename ValueType,
20753 int > = 0 >
20754 ValueType & get_to(ValueType& v) const noexcept(noexcept(
20755 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20756 {
20758 return v;
20759 }
20760
20761 // specialization to allow calling get_to with a basic_json value
20762 // see https://github.com/nlohmann/json/issues/2175
20763 template<typename ValueType,
20766 int> = 0>
20767 ValueType & get_to(ValueType& v) const
20768 {
20769 v = *this;
20770 return v;
20771 }
20772
20773 template <
20774 typename T, std::size_t N,
20775 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20778 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20779 noexcept(noexcept(JSONSerializer<Array>::from_json(
20780 std::declval<const basic_json_t&>(), v)))
20781 {
20783 return v;
20784 }
20785
20788 template<typename ReferenceType, typename std::enable_if<
20789 std::is_reference<ReferenceType>::value, int>::type = 0>
20790 ReferenceType get_ref()
20791 {
20792 // delegate call to get_ref_impl
20793 return get_ref_impl<ReferenceType>(*this);
20794 }
20795
20798 template < typename ReferenceType, typename std::enable_if <
20799 std::is_reference<ReferenceType>::value&&
20800 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20801 ReferenceType get_ref() const
20802 {
20803 // delegate call to get_ref_impl
20804 return get_ref_impl<ReferenceType>(*this);
20805 }
20806
20836 template < typename ValueType, typename std::enable_if <
20844#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20846#endif
20847#if defined(JSON_HAS_CPP_17)
20849#endif
20851 >::value, int >::type = 0 >
20852 JSON_EXPLICIT operator ValueType() const
20853 {
20854 // delegate the call to get<>() const
20855 return get<ValueType>();
20856 }
20857
20861 {
20862 if (!is_binary())
20863 {
20864 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20865 }
20866
20867 return *get_ptr<binary_t*>();
20868 }
20869
20872 const binary_t& get_binary() const
20873 {
20874 if (!is_binary())
20875 {
20876 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20877 }
20878
20879 return *get_ptr<const binary_t*>();
20880 }
20881
20883
20884
20886 // element access //
20888
20892
20896 {
20897 // at only works for arrays
20898 if (JSON_HEDLEY_LIKELY(is_array()))
20899 {
20900 JSON_TRY
20901 {
20902 return set_parent(m_value.array->at(idx));
20903 }
20904 JSON_CATCH (std::out_of_range&)
20905 {
20906 // create better exception explanation
20907 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20908 }
20909 }
20910 else
20911 {
20912 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20913 }
20914 }
20915
20919 {
20920 // at only works for arrays
20921 if (JSON_HEDLEY_LIKELY(is_array()))
20922 {
20923 JSON_TRY
20924 {
20925 return m_value.array->at(idx);
20926 }
20927 JSON_CATCH (std::out_of_range&)
20928 {
20929 // create better exception explanation
20930 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20931 }
20932 }
20933 else
20934 {
20935 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20936 }
20937 }
20938
20941 reference at(const typename object_t::key_type& key)
20942 {
20943 // at only works for objects
20944 if (JSON_HEDLEY_UNLIKELY(!is_object()))
20945 {
20946 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20947 }
20948
20949 auto it = m_value.object->find(key);
20950 if (it == m_value.object->end())
20951 {
20952 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20953 }
20954 return set_parent(it->second);
20955 }
20956
20959 template<class KeyType, detail::enable_if_t<
20961 reference at(KeyType && key)
20962 {
20963 // at only works for objects
20964 if (JSON_HEDLEY_UNLIKELY(!is_object()))
20965 {
20966 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20967 }
20968
20969 auto it = m_value.object->find(std::forward<KeyType>(key));
20970 if (it == m_value.object->end())
20971 {
20972 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20973 }
20974 return set_parent(it->second);
20975 }
20976
20979 const_reference at(const typename object_t::key_type& key) const
20980 {
20981 // at only works for objects
20982 if (JSON_HEDLEY_UNLIKELY(!is_object()))
20983 {
20984 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20985 }
20986
20987 auto it = m_value.object->find(key);
20988 if (it == m_value.object->end())
20989 {
20990 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20991 }
20992 return it->second;
20993 }
20994
20997 template<class KeyType, detail::enable_if_t<
20999 const_reference at(KeyType && key) const
21000 {
21001 // at only works for objects
21002 if (JSON_HEDLEY_UNLIKELY(!is_object()))
21003 {
21004 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21005 }
21006
21007 auto it = m_value.object->find(std::forward<KeyType>(key));
21008 if (it == m_value.object->end())
21009 {
21010 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21011 }
21012 return it->second;
21013 }
21014
21018 {
21019 // implicitly convert null value to an empty array
21020 if (is_null())
21021 {
21022 m_type = value_t::array;
21023 m_value.array = create<array_t>();
21024 assert_invariant();
21025 }
21026
21027 // operator[] only works for arrays
21028 if (JSON_HEDLEY_LIKELY(is_array()))
21029 {
21030 // fill up array with null values if given idx is outside range
21031 if (idx >= m_value.array->size())
21032 {
21033#if JSON_DIAGNOSTICS
21034 // remember array size & capacity before resizing
21035 const auto old_size = m_value.array->size();
21036 const auto old_capacity = m_value.array->capacity();
21037#endif
21038 m_value.array->resize(idx + 1);
21039
21040#if JSON_DIAGNOSTICS
21041 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
21042 {
21043 // capacity has changed: update all parents
21044 set_parents();
21045 }
21046 else
21047 {
21048 // set parent for values added above
21049 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21050 }
21051#endif
21052 assert_invariant();
21053 }
21054
21055 return m_value.array->operator[](idx);
21056 }
21057
21058 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21059 }
21060
21064 {
21065 // const operator[] only works for arrays
21066 if (JSON_HEDLEY_LIKELY(is_array()))
21067 {
21068 return m_value.array->operator[](idx);
21069 }
21070
21071 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21072 }
21073
21076 reference operator[](typename object_t::key_type key)
21077 {
21078 // implicitly convert null value to an empty object
21079 if (is_null())
21080 {
21081 m_type = value_t::object;
21082 m_value.object = create<object_t>();
21083 assert_invariant();
21084 }
21085
21086 // operator[] only works for objects
21087 if (JSON_HEDLEY_LIKELY(is_object()))
21088 {
21089 auto result = m_value.object->emplace(std::move(key), nullptr);
21090 return set_parent(result.first->second);
21091 }
21092
21093 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21094 }
21095
21098 const_reference operator[](const typename object_t::key_type& key) const
21099 {
21100 // const operator[] only works for objects
21101 if (JSON_HEDLEY_LIKELY(is_object()))
21102 {
21103 auto it = m_value.object->find(key);
21104 JSON_ASSERT(it != m_value.object->end());
21105 return it->second;
21106 }
21107
21108 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21109 }
21110
21111 // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
21112 // (they seemingly cannot be constrained to resolve the ambiguity)
21113 template<typename T>
21115 {
21116 return operator[](typename object_t::key_type(key));
21117 }
21118
21119 template<typename T>
21121 {
21122 return operator[](typename object_t::key_type(key));
21123 }
21124
21127 template<class KeyType, detail::enable_if_t<
21130 {
21131 // implicitly convert null value to an empty object
21132 if (is_null())
21133 {
21134 m_type = value_t::object;
21135 m_value.object = create<object_t>();
21136 assert_invariant();
21137 }
21138
21139 // operator[] only works for objects
21140 if (JSON_HEDLEY_LIKELY(is_object()))
21141 {
21142 auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr);
21143 return set_parent(result.first->second);
21144 }
21145
21146 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21147 }
21148
21151 template<class KeyType, detail::enable_if_t<
21154 {
21155 // const operator[] only works for objects
21156 if (JSON_HEDLEY_LIKELY(is_object()))
21157 {
21158 auto it = m_value.object->find(std::forward<KeyType>(key));
21159 JSON_ASSERT(it != m_value.object->end());
21160 return it->second;
21161 }
21162
21163 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21164 }
21165
21168 // this is the value(const typename object_t::key_type&) overload
21169 template < class KeyType, class ValueType, detail::enable_if_t <
21170 std::is_same<KeyType, typename object_t::key_type>::value
21172 && !std::is_same<value_t, ValueType>::value, int > = 0 >
21173 typename std::decay<ValueType>::type value(const KeyType& key, ValueType && default_value) const
21174 {
21175 // value only works for objects
21176 if (JSON_HEDLEY_LIKELY(is_object()))
21177 {
21178 // if key is found, return value and given default value otherwise
21179 const auto it = find(key);
21180 if (it != end())
21181 {
21182 return it->template get<typename std::decay<ValueType>::type>();
21183 }
21184
21185 return std::forward<ValueType>(default_value);
21186 }
21187
21188 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21189 }
21190
21194 string_t value(const typename object_t::key_type& key, const char* default_value) const
21195 {
21196 return value(key, string_t(default_value));
21197 }
21198
21199 // these two functions, in conjunction with value(const KeyType &, ValueType &&),
21200 // resolve an ambiguity that would otherwise occur between the json_pointer and
21201 // typename object_t::key_type & overloads
21202 template < class ValueType, detail::enable_if_t <
21204 && !std::is_same<value_t, ValueType>::value, int > = 0 >
21205 typename std::decay<ValueType>::type value(const char* key, ValueType && default_value) const
21206 {
21207 return value(typename object_t::key_type(key), std::forward<ValueType>(default_value));
21208 }
21209
21210 string_t value(const char* key, const char* default_value) const
21211 {
21212 return value(typename object_t::key_type(key), string_t(default_value));
21213 }
21214
21218 template < class KeyType, class ValueType, detail::enable_if_t <
21220 && !std::is_same<value_t, ValueType>::value
21222 typename std::decay<ValueType>::type value(KeyType && key, ValueType && default_value) const
21223 {
21224 // value only works for objects
21225 if (JSON_HEDLEY_LIKELY(is_object()))
21226 {
21227 // if key is found, return value and given default value otherwise
21228 const auto it = find(std::forward<KeyType>(key));
21229 if (it != end())
21230 {
21231 return it->template get<typename std::decay<ValueType>::type>();
21232 }
21233
21234 return std::forward<ValueType>(default_value);
21235 }
21236
21237 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21238 }
21239
21243 template < class KeyType, detail::enable_if_t <
21245 string_t value(KeyType && key, const char* default_value) const
21246 {
21247 return value(std::forward<KeyType>(key), string_t(default_value));
21248 }
21249
21252 template < class ValueType, detail::enable_if_t <
21254 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21255 {
21256 // value only works for objects
21257 if (JSON_HEDLEY_LIKELY(is_object()))
21258 {
21259 // if pointer resolves a value, return it or use default value
21260 JSON_TRY
21261 {
21262 return ptr.get_checked(this).template get<ValueType>();
21263 }
21265 {
21266 return default_value;
21267 }
21268 }
21269
21270 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21271 }
21272
21273 template < class ValueType, class BasicJsonType, detail::enable_if_t <
21275 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21276 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
21277 {
21278 return value(ptr.convert(), default_value);
21279 }
21280
21285 string_t value(const json_pointer& ptr, const char* default_value) const
21286 {
21287 return value(ptr, string_t(default_value));
21288 }
21289
21290 template<typename BasicJsonType>
21291 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21293 string_t value(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr, const char* default_value) const
21294 {
21295 return value(ptr.convert(), default_value);
21296 }
21297
21300 reference front()
21301 {
21302 return *begin();
21303 }
21304
21308 {
21309 return *cbegin();
21310 }
21311
21315 {
21316 auto tmp = end();
21317 --tmp;
21318 return *tmp;
21319 }
21320
21324 {
21325 auto tmp = cend();
21326 --tmp;
21327 return *tmp;
21328 }
21329
21332 template < class IteratorType, detail::enable_if_t <
21333 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21334 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21335 IteratorType erase(IteratorType pos)
21336 {
21337 // make sure iterator fits the current value
21338 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21339 {
21340 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21341 }
21342
21343 IteratorType result = end();
21344
21345 switch (m_type)
21346 {
21347 case value_t::boolean:
21348 case value_t::number_float:
21349 case value_t::number_integer:
21350 case value_t::number_unsigned:
21351 case value_t::string:
21352 case value_t::binary:
21353 {
21354 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21355 {
21356 JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
21357 }
21358
21359 if (is_string())
21360 {
21361 AllocatorType<string_t> alloc;
21362 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21363 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21364 m_value.string = nullptr;
21365 }
21366 else if (is_binary())
21367 {
21368 AllocatorType<binary_t> alloc;
21369 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21370 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21371 m_value.binary = nullptr;
21372 }
21373
21374 m_type = value_t::null;
21375 assert_invariant();
21376 break;
21377 }
21378
21379 case value_t::object:
21380 {
21381 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21382 break;
21383 }
21384
21385 case value_t::array:
21386 {
21387 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21388 break;
21389 }
21390
21391 case value_t::null:
21392 case value_t::discarded:
21393 default:
21394 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21395 }
21396
21397 return result;
21398 }
21399
21402 template < class IteratorType, detail::enable_if_t <
21403 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21404 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21405 IteratorType erase(IteratorType first, IteratorType last)
21406 {
21407 // make sure iterator fits the current value
21408 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21409 {
21410 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
21411 }
21412
21413 IteratorType result = end();
21414
21415 switch (m_type)
21416 {
21417 case value_t::boolean:
21418 case value_t::number_float:
21419 case value_t::number_integer:
21420 case value_t::number_unsigned:
21421 case value_t::string:
21422 case value_t::binary:
21423 {
21424 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21425 || !last.m_it.primitive_iterator.is_end()))
21426 {
21427 JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21428 }
21429
21430 if (is_string())
21431 {
21432 AllocatorType<string_t> alloc;
21433 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21434 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21435 m_value.string = nullptr;
21436 }
21437 else if (is_binary())
21438 {
21439 AllocatorType<binary_t> alloc;
21440 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21441 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21442 m_value.binary = nullptr;
21443 }
21444
21445 m_type = value_t::null;
21446 assert_invariant();
21447 break;
21448 }
21449
21450 case value_t::object:
21451 {
21452 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21453 last.m_it.object_iterator);
21454 break;
21455 }
21456
21457 case value_t::array:
21458 {
21459 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21460 last.m_it.array_iterator);
21461 break;
21462 }
21463
21464 case value_t::null:
21465 case value_t::discarded:
21466 default:
21467 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21468 }
21469
21470 return result;
21471 }
21472
21473 private:
21474 template < typename KeyType, detail::enable_if_t <
21477 {
21478 // this erase only works for objects
21479 if (JSON_HEDLEY_UNLIKELY(!is_object()))
21480 {
21481 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21482 }
21483
21484 return m_value.object->erase(std::forward<KeyType>(key));
21485 }
21486
21487 template < typename KeyType, detail::enable_if_t <
21490 {
21491 // this erase only works for objects
21492 if (JSON_HEDLEY_UNLIKELY(!is_object()))
21493 {
21494 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21495 }
21496
21497 const auto it = m_value.object->find(std::forward<KeyType>(key));
21498 if (it != m_value.object->end())
21499 {
21500 m_value.object->erase(it);
21501 return 1;
21502 }
21503 return 0;
21504 }
21505
21506 public:
21507
21510 size_type erase(const typename object_t::key_type& key)
21511 {
21512 // the indirection via erase_internal() is added to avoid making this
21513 // function a template and thus de-rank it during overload resolution
21514 return erase_internal(key);
21515 }
21516
21519 template<class KeyType, detail::enable_if_t<
21521 size_type erase(KeyType && key)
21522 {
21523 return erase_internal(std::forward<KeyType>(key));
21524 }
21525
21528 void erase(const size_type idx)
21529 {
21530 // this erase only works for arrays
21531 if (JSON_HEDLEY_LIKELY(is_array()))
21532 {
21533 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21534 {
21535 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21536 }
21537
21538 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21539 }
21540 else
21541 {
21542 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21543 }
21544 }
21545
21547
21548
21550 // lookup //
21552
21555
21558 iterator find(const typename object_t::key_type& key)
21559 {
21560 auto result = end();
21561
21562 if (is_object())
21563 {
21564 result.m_it.object_iterator = m_value.object->find(key);
21565 }
21566
21567 return result;
21568 }
21569
21572 const_iterator find(const typename object_t::key_type& key) const
21573 {
21574 auto result = cend();
21575
21576 if (is_object())
21577 {
21578 result.m_it.object_iterator = m_value.object->find(key);
21579 }
21580
21581 return result;
21582 }
21583
21586 template<class KeyType, detail::enable_if_t<
21588 iterator find(KeyType && key)
21589 {
21590 auto result = end();
21591
21592 if (is_object())
21593 {
21594 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
21595 }
21596
21597 return result;
21598 }
21599
21602 template<class KeyType, detail::enable_if_t<
21604 const_iterator find(KeyType && key) const
21605 {
21606 auto result = cend();
21607
21608 if (is_object())
21609 {
21610 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
21611 }
21612
21613 return result;
21614 }
21615
21618 size_type count(const typename object_t::key_type& key) const
21619 {
21620 // return 0 for all nonobject types
21621 return is_object() ? m_value.object->count(key) : 0;
21622 }
21623
21626 template<class KeyType, detail::enable_if_t<
21628 size_type count(KeyType && key) const
21629 {
21630 // return 0 for all nonobject types
21631 return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0;
21632 }
21633
21636 bool contains(const typename object_t::key_type& key) const
21637 {
21638 return is_object() && m_value.object->find(key) != m_value.object->end();
21639 }
21640
21643 template<class KeyType, detail::enable_if_t<
21645 bool contains(KeyType && key) const
21646 {
21647 return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end();
21648 }
21649
21652 bool contains(const json_pointer& ptr) const
21653 {
21654 return ptr.contains(this);
21655 }
21656
21657 template<typename BasicJsonType>
21658 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21659 bool contains(const typename ::nlohmann::json_pointer<BasicJsonType> ptr) const
21660 {
21661 return ptr.contains(this);
21662 }
21663
21665
21666
21668 // iterators //
21670
21673
21676 iterator begin() noexcept
21677 {
21678 iterator result(this);
21679 result.set_begin();
21680 return result;
21681 }
21682
21685 const_iterator begin() const noexcept
21686 {
21687 return cbegin();
21688 }
21689
21692 const_iterator cbegin() const noexcept
21693 {
21694 const_iterator result(this);
21695 result.set_begin();
21696 return result;
21697 }
21698
21701 iterator end() noexcept
21702 {
21703 iterator result(this);
21704 result.set_end();
21705 return result;
21706 }
21707
21710 const_iterator end() const noexcept
21711 {
21712 return cend();
21713 }
21714
21717 const_iterator cend() const noexcept
21718 {
21719 const_iterator result(this);
21720 result.set_end();
21721 return result;
21722 }
21723
21726 reverse_iterator rbegin() noexcept
21727 {
21728 return reverse_iterator(end());
21729 }
21730
21733 const_reverse_iterator rbegin() const noexcept
21734 {
21735 return crbegin();
21736 }
21737
21740 reverse_iterator rend() noexcept
21741 {
21742 return reverse_iterator(begin());
21743 }
21744
21747 const_reverse_iterator rend() const noexcept
21748 {
21749 return crend();
21750 }
21751
21754 const_reverse_iterator crbegin() const noexcept
21755 {
21756 return const_reverse_iterator(cend());
21757 }
21758
21761 const_reverse_iterator crend() const noexcept
21762 {
21763 return const_reverse_iterator(cbegin());
21764 }
21765
21766 public:
21772 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21773 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21774 {
21775 return ref.items();
21776 }
21777
21783 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21784 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21785 {
21786 return ref.items();
21787 }
21788
21791 iteration_proxy<iterator> items() noexcept
21792 {
21793 return iteration_proxy<iterator>(*this);
21794 }
21795
21798 iteration_proxy<const_iterator> items() const noexcept
21799 {
21800 return iteration_proxy<const_iterator>(*this);
21801 }
21802
21804
21805
21807 // capacity //
21809
21812
21815 bool empty() const noexcept
21816 {
21817 switch (m_type)
21818 {
21819 case value_t::null:
21820 {
21821 // null values are empty
21822 return true;
21823 }
21824
21825 case value_t::array:
21826 {
21827 // delegate call to array_t::empty()
21828 return m_value.array->empty();
21829 }
21830
21831 case value_t::object:
21832 {
21833 // delegate call to object_t::empty()
21834 return m_value.object->empty();
21835 }
21836
21837 case value_t::string:
21838 case value_t::boolean:
21839 case value_t::number_integer:
21840 case value_t::number_unsigned:
21841 case value_t::number_float:
21842 case value_t::binary:
21843 case value_t::discarded:
21844 default:
21845 {
21846 // all other types are nonempty
21847 return false;
21848 }
21849 }
21850 }
21851
21854 size_type size() const noexcept
21855 {
21856 switch (m_type)
21857 {
21858 case value_t::null:
21859 {
21860 // null values are empty
21861 return 0;
21862 }
21863
21864 case value_t::array:
21865 {
21866 // delegate call to array_t::size()
21867 return m_value.array->size();
21868 }
21869
21870 case value_t::object:
21871 {
21872 // delegate call to object_t::size()
21873 return m_value.object->size();
21874 }
21875
21876 case value_t::string:
21877 case value_t::boolean:
21878 case value_t::number_integer:
21879 case value_t::number_unsigned:
21880 case value_t::number_float:
21881 case value_t::binary:
21882 case value_t::discarded:
21883 default:
21884 {
21885 // all other types have size 1
21886 return 1;
21887 }
21888 }
21889 }
21890
21893 size_type max_size() const noexcept
21894 {
21895 switch (m_type)
21896 {
21897 case value_t::array:
21898 {
21899 // delegate call to array_t::max_size()
21900 return m_value.array->max_size();
21901 }
21902
21903 case value_t::object:
21904 {
21905 // delegate call to object_t::max_size()
21906 return m_value.object->max_size();
21907 }
21908
21909 case value_t::null:
21910 case value_t::string:
21911 case value_t::boolean:
21912 case value_t::number_integer:
21913 case value_t::number_unsigned:
21914 case value_t::number_float:
21915 case value_t::binary:
21916 case value_t::discarded:
21917 default:
21918 {
21919 // all other types have max_size() == size()
21920 return size();
21921 }
21922 }
21923 }
21924
21926
21927
21929 // modifiers //
21931
21934
21937 void clear() noexcept
21938 {
21939 switch (m_type)
21940 {
21941 case value_t::number_integer:
21942 {
21943 m_value.number_integer = 0;
21944 break;
21945 }
21946
21947 case value_t::number_unsigned:
21948 {
21949 m_value.number_unsigned = 0;
21950 break;
21951 }
21952
21953 case value_t::number_float:
21954 {
21955 m_value.number_float = 0.0;
21956 break;
21957 }
21958
21959 case value_t::boolean:
21960 {
21961 m_value.boolean = false;
21962 break;
21963 }
21964
21965 case value_t::string:
21966 {
21967 m_value.string->clear();
21968 break;
21969 }
21970
21971 case value_t::binary:
21972 {
21973 m_value.binary->clear();
21974 break;
21975 }
21976
21977 case value_t::array:
21978 {
21979 m_value.array->clear();
21980 break;
21981 }
21982
21983 case value_t::object:
21984 {
21985 m_value.object->clear();
21986 break;
21987 }
21988
21989 case value_t::null:
21990 case value_t::discarded:
21991 default:
21992 break;
21993 }
21994 }
21995
21998 void push_back(basic_json&& val)
21999 {
22000 // push_back only works for null objects or arrays
22001 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22002 {
22003 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22004 }
22005
22006 // transform null object into an array
22007 if (is_null())
22008 {
22009 m_type = value_t::array;
22010 m_value = value_t::array;
22011 assert_invariant();
22012 }
22013
22014 // add element to array (move semantics)
22015 const auto old_capacity = m_value.array->capacity();
22016 m_value.array->push_back(std::move(val));
22017 set_parent(m_value.array->back(), old_capacity);
22018 // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
22019 }
22020
22024 {
22025 push_back(std::move(val));
22026 return *this;
22027 }
22028
22031 void push_back(const basic_json& val)
22032 {
22033 // push_back only works for null objects or arrays
22034 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22035 {
22036 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22037 }
22038
22039 // transform null object into an array
22040 if (is_null())
22041 {
22042 m_type = value_t::array;
22043 m_value = value_t::array;
22044 assert_invariant();
22045 }
22046
22047 // add element to array
22048 const auto old_capacity = m_value.array->capacity();
22049 m_value.array->push_back(val);
22050 set_parent(m_value.array->back(), old_capacity);
22051 }
22052
22056 {
22057 push_back(val);
22058 return *this;
22059 }
22060
22063 void push_back(const typename object_t::value_type& val)
22064 {
22065 // push_back only works for null objects or objects
22066 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22067 {
22068 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22069 }
22070
22071 // transform null object into an object
22072 if (is_null())
22073 {
22074 m_type = value_t::object;
22075 m_value = value_t::object;
22076 assert_invariant();
22077 }
22078
22079 // add element to object
22080 auto res = m_value.object->insert(val);
22081 set_parent(res.first->second);
22082 }
22083
22086 reference operator+=(const typename object_t::value_type& val)
22087 {
22088 push_back(val);
22089 return *this;
22090 }
22091
22095 {
22096 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22097 {
22098 basic_json&& key = init.begin()->moved_or_copied();
22099 push_back(typename object_t::value_type(
22100 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22101 }
22102 else
22103 {
22104 push_back(basic_json(init));
22105 }
22106 }
22107
22111 {
22112 push_back(init);
22113 return *this;
22114 }
22115
22118 template<class... Args>
22119 reference emplace_back(Args&& ... args)
22120 {
22121 // emplace_back only works for null objects or arrays
22122 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22123 {
22124 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
22125 }
22126
22127 // transform null object into an array
22128 if (is_null())
22129 {
22130 m_type = value_t::array;
22131 m_value = value_t::array;
22132 assert_invariant();
22133 }
22134
22135 // add element to array (perfect forwarding)
22136 const auto old_capacity = m_value.array->capacity();
22137 m_value.array->emplace_back(std::forward<Args>(args)...);
22138 return set_parent(m_value.array->back(), old_capacity);
22139 }
22140
22143 template<class... Args>
22144 std::pair<iterator, bool> emplace(Args&& ... args)
22145 {
22146 // emplace only works for null objects or arrays
22147 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22148 {
22149 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
22150 }
22151
22152 // transform null object into an object
22153 if (is_null())
22154 {
22155 m_type = value_t::object;
22156 m_value = value_t::object;
22157 assert_invariant();
22158 }
22159
22160 // add element to array (perfect forwarding)
22161 auto res = m_value.object->emplace(std::forward<Args>(args)...);
22162 set_parent(res.first->second);
22163
22164 // create result iterator and set iterator to the result of emplace
22165 auto it = begin();
22166 it.m_it.object_iterator = res.first;
22167
22168 // return pair of iterator and boolean
22169 return {it, res.second};
22170 }
22171
22175 template<typename... Args>
22177 {
22178 iterator result(this);
22179 JSON_ASSERT(m_value.array != nullptr);
22180
22181 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22182 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22183 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22184
22185 // This could have been written as:
22186 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22187 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22188
22189 set_parents();
22190 return result;
22191 }
22192
22196 {
22197 // insert only works for arrays
22198 if (JSON_HEDLEY_LIKELY(is_array()))
22199 {
22200 // check if iterator pos fits to this JSON value
22201 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22202 {
22203 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22204 }
22205
22206 // insert to array and return iterator
22207 return insert_iterator(pos, val);
22208 }
22209
22210 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22211 }
22212
22216 {
22217 return insert(pos, val);
22218 }
22219
22223 {
22224 // insert only works for arrays
22225 if (JSON_HEDLEY_LIKELY(is_array()))
22226 {
22227 // check if iterator pos fits to this JSON value
22228 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22229 {
22230 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22231 }
22232
22233 // insert to array and return iterator
22234 return insert_iterator(pos, cnt, val);
22235 }
22236
22237 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22238 }
22239
22243 {
22244 // insert only works for arrays
22245 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22246 {
22247 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22248 }
22249
22250 // check if iterator pos fits to this JSON value
22251 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22252 {
22253 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22254 }
22255
22256 // check if range iterators belong to the same JSON object
22257 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22258 {
22259 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22260 }
22261
22262 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22263 {
22264 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
22265 }
22266
22267 // insert to array and return iterator
22268 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22269 }
22270
22274 {
22275 // insert only works for arrays
22276 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22277 {
22278 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22279 }
22280
22281 // check if iterator pos fits to this JSON value
22282 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22283 {
22284 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22285 }
22286
22287 // insert to array and return iterator
22288 return insert_iterator(pos, ilist.begin(), ilist.end());
22289 }
22290
22294 {
22295 // insert only works for objects
22296 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22297 {
22298 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22299 }
22300
22301 // check if range iterators belong to the same JSON object
22302 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22303 {
22304 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22305 }
22306
22307 // passed iterators must belong to objects
22308 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22309 {
22310 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
22311 }
22312
22313 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22314 }
22315
22318 void update(const_reference j, bool merge_objects = false)
22319 {
22320 update(j.begin(), j.end(), merge_objects);
22321 }
22322
22325 void update(const_iterator first, const_iterator last, bool merge_objects = false)
22326 {
22327 // implicitly convert null value to an empty object
22328 if (is_null())
22329 {
22330 m_type = value_t::object;
22331 m_value.object = create<object_t>();
22332 assert_invariant();
22333 }
22334
22335 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22336 {
22337 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
22338 }
22339
22340 // check if range iterators belong to the same JSON object
22341 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22342 {
22343 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22344 }
22345
22346 // passed iterators must belong to objects
22347 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22348 {
22349 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
22350 }
22351
22352 for (auto it = first; it != last; ++it)
22353 {
22354 if (merge_objects && it.value().is_object())
22355 {
22356 auto it2 = m_value.object->find(it.key());
22357 if (it2 != m_value.object->end())
22358 {
22359 it2->second.update(it.value(), true);
22360 continue;
22361 }
22362 }
22363 m_value.object->operator[](it.key()) = it.value();
22364#if JSON_DIAGNOSTICS
22365 m_value.object->operator[](it.key()).m_parent = this;
22366#endif
22367 }
22368 }
22369
22372 void swap(reference other) noexcept (
22373 std::is_nothrow_move_constructible<value_t>::value&&
22374 std::is_nothrow_move_assignable<value_t>::value&&
22375 std::is_nothrow_move_constructible<json_value>::value&&
22376 std::is_nothrow_move_assignable<json_value>::value
22377 )
22378 {
22379 std::swap(m_type, other.m_type);
22380 std::swap(m_value, other.m_value);
22381
22382 set_parents();
22383 other.set_parents();
22384 assert_invariant();
22385 }
22386
22389 friend void swap(reference left, reference right) noexcept (
22390 std::is_nothrow_move_constructible<value_t>::value&&
22391 std::is_nothrow_move_assignable<value_t>::value&&
22392 std::is_nothrow_move_constructible<json_value>::value&&
22393 std::is_nothrow_move_assignable<json_value>::value
22394 )
22395 {
22396 left.swap(right);
22397 }
22398
22401 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
22402 {
22403 // swap only works for arrays
22404 if (JSON_HEDLEY_LIKELY(is_array()))
22405 {
22406 using std::swap;
22407 swap(*(m_value.array), other);
22408 }
22409 else
22410 {
22411 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
22412 }
22413 }
22414
22417 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
22418 {
22419 // swap only works for objects
22420 if (JSON_HEDLEY_LIKELY(is_object()))
22421 {
22422 using std::swap;
22423 swap(*(m_value.object), other);
22424 }
22425 else
22426 {
22427 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
22428 }
22429 }
22430
22433 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
22434 {
22435 // swap only works for strings
22436 if (JSON_HEDLEY_LIKELY(is_string()))
22437 {
22438 using std::swap;
22439 swap(*(m_value.string), other);
22440 }
22441 else
22442 {
22443 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
22444 }
22445 }
22446
22449 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
22450 {
22451 // swap only works for strings
22452 if (JSON_HEDLEY_LIKELY(is_binary()))
22453 {
22454 using std::swap;
22455 swap(*(m_value.binary), other);
22456 }
22457 else
22458 {
22459 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
22460 }
22461 }
22462
22465 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22466 {
22467 // swap only works for strings
22468 if (JSON_HEDLEY_LIKELY(is_binary()))
22469 {
22470 using std::swap;
22471 swap(*(m_value.binary), other);
22472 }
22473 else
22474 {
22475 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
22476 }
22477 }
22478
22480
22482 // lexicographical comparison operators //
22484
22487
22488 // note parentheses around operands are necessary; see
22489 // https://github.com/nlohmann/json/issues/1530
22490#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22491 const auto lhs_type = lhs.type(); \
22492 const auto rhs_type = rhs.type(); \
22493 \
22494 if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22495 { \
22496 switch (lhs_type) \
22497 { \
22498 case value_t::array: \
22499 return (*lhs.m_value.array) op (*rhs.m_value.array); \
22500 \
22501 case value_t::object: \
22502 return (*lhs.m_value.object) op (*rhs.m_value.object); \
22503 \
22504 case value_t::null: \
22505 return (null_result); \
22506 \
22507 case value_t::string: \
22508 return (*lhs.m_value.string) op (*rhs.m_value.string); \
22509 \
22510 case value_t::boolean: \
22511 return (lhs.m_value.boolean) op (rhs.m_value.boolean); \
22512 \
22513 case value_t::number_integer: \
22514 return (lhs.m_value.number_integer) op (rhs.m_value.number_integer); \
22515 \
22516 case value_t::number_unsigned: \
22517 return (lhs.m_value.number_unsigned) op (rhs.m_value.number_unsigned); \
22518 \
22519 case value_t::number_float: \
22520 return (lhs.m_value.number_float) op (rhs.m_value.number_float); \
22521 \
22522 case value_t::binary: \
22523 return (*lhs.m_value.binary) op (*rhs.m_value.binary); \
22524 \
22525 case value_t::discarded: \
22526 default: \
22527 return (unordered_result); \
22528 } \
22529 } \
22530 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22531 { \
22532 return static_cast<number_float_t>(lhs.m_value.number_integer) op rhs.m_value.number_float; \
22533 } \
22534 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22535 { \
22536 return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_integer); \
22537 } \
22538 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22539 { \
22540 return static_cast<number_float_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_float; \
22541 } \
22542 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22543 { \
22544 return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_unsigned); \
22545 } \
22546 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22547 { \
22548 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_integer; \
22549 } \
22550 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22551 { \
22552 return lhs.m_value.number_integer op static_cast<number_integer_t>(rhs.m_value.number_unsigned); \
22553 } \
22554 else if(compares_unordered(lhs, rhs))\
22555 {\
22556 return (unordered_result);\
22557 }\
22558 \
22559 return (default_result);
22560
22562 // returns true if:
22563 // - any operand is NaN and the other operand is of number type
22564 // - any operand is discarded
22565 // in legacy mode, discarded values are considered ordered if
22566 // an operation is computed as an odd number of inverses of others
22567 static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22568 {
22569 if ((lhs.is_number_float() && std::isnan(lhs.m_value.number_float) && rhs.is_number())
22570 || (rhs.is_number_float() && std::isnan(rhs.m_value.number_float) && lhs.is_number()))
22571 {
22572 return true;
22573 }
22574#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22575 return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22576#else
22577 static_cast<void>(inverse);
22578 return lhs.is_discarded() || rhs.is_discarded();
22579#endif
22580 }
22581
22582 private:
22583 bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22584 {
22585 return compares_unordered(*this, rhs, inverse);
22586 }
22587
22588 public:
22589#if JSON_HAS_THREE_WAY_COMPARISON
22592 bool operator==(const_reference rhs) const noexcept
22593 {
22594#ifdef __GNUC__
22595#pragma GCC diagnostic push
22596#pragma GCC diagnostic ignored "-Wfloat-equal"
22597#endif
22598 const_reference lhs = *this;
22599 JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22600#ifdef __GNUC__
22601#pragma GCC diagnostic pop
22602#endif
22603 }
22604
22607 template<typename ScalarType>
22608 requires std::is_scalar_v<ScalarType>
22609 bool operator==(ScalarType rhs) const noexcept
22610 {
22611 return *this == basic_json(rhs);
22612 }
22613
22616 bool operator!=(const_reference rhs) const noexcept
22617 {
22618 if (compares_unordered(rhs, true))
22619 {
22620 return false;
22621 }
22622 return !operator==(rhs);
22623 }
22624
22627 std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
22628 {
22629 const_reference lhs = *this;
22630 // default_result is used if we cannot compare values. In that case,
22631 // we compare types.
22632 JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
22633 std::partial_ordering::equivalent,
22634 std::partial_ordering::unordered,
22635 lhs_type <=> rhs_type) // *NOPAD*
22636 }
22637
22640 template<typename ScalarType>
22641 requires std::is_scalar_v<ScalarType>
22642 std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
22643 {
22644 return *this <=> basic_json(rhs); // *NOPAD*
22645 }
22646
22647#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22648 // all operators that are computed as an odd number of inverses of others
22649 // need to be overloaded to emulate the legacy comparison behavior
22650
22654 bool operator<=(const_reference rhs) const noexcept
22655 {
22656 if (compares_unordered(rhs, true))
22657 {
22658 return false;
22659 }
22660 return !(rhs < *this);
22661 }
22662
22665 template<typename ScalarType>
22666 requires std::is_scalar_v<ScalarType>
22667 bool operator<=(ScalarType rhs) const noexcept
22668 {
22669 return *this <= basic_json(rhs);
22670 }
22671
22675 bool operator>=(const_reference rhs) const noexcept
22676 {
22677 if (compares_unordered(rhs, true))
22678 {
22679 return false;
22680 }
22681 return !(*this < rhs);
22682 }
22683
22686 template<typename ScalarType>
22687 requires std::is_scalar_v<ScalarType>
22688 bool operator>=(ScalarType rhs) const noexcept
22689 {
22690 return *this >= basic_json(rhs);
22691 }
22692#endif
22693#else
22696 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22697 {
22698#ifdef __GNUC__
22699#pragma GCC diagnostic push
22700#pragma GCC diagnostic ignored "-Wfloat-equal"
22701#endif
22702 JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22703#ifdef __GNUC__
22704#pragma GCC diagnostic pop
22705#endif
22706 }
22707
22710 template<typename ScalarType, typename std::enable_if<
22711 std::is_scalar<ScalarType>::value, int>::type = 0>
22712 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
22713 {
22714 return lhs == basic_json(rhs);
22715 }
22716
22719 template<typename ScalarType, typename std::enable_if<
22720 std::is_scalar<ScalarType>::value, int>::type = 0>
22721 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
22722 {
22723 return basic_json(lhs) == rhs;
22724 }
22725
22728 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22729 {
22730 if (compares_unordered(lhs, rhs, true))
22731 {
22732 return false;
22733 }
22734 return !(lhs == rhs);
22735 }
22736
22739 template<typename ScalarType, typename std::enable_if<
22740 std::is_scalar<ScalarType>::value, int>::type = 0>
22741 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
22742 {
22743 return lhs != basic_json(rhs);
22744 }
22745
22748 template<typename ScalarType, typename std::enable_if<
22749 std::is_scalar<ScalarType>::value, int>::type = 0>
22750 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
22751 {
22752 return basic_json(lhs) != rhs;
22753 }
22754
22757 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22758 {
22759 // default_result is used if we cannot compare values. In that case,
22760 // we compare types. Note we have to call the operator explicitly,
22761 // because MSVC has problems otherwise.
22762 JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
22763 }
22764
22767 template<typename ScalarType, typename std::enable_if<
22768 std::is_scalar<ScalarType>::value, int>::type = 0>
22769 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
22770 {
22771 return lhs < basic_json(rhs);
22772 }
22773
22776 template<typename ScalarType, typename std::enable_if<
22777 std::is_scalar<ScalarType>::value, int>::type = 0>
22778 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
22779 {
22780 return basic_json(lhs) < rhs;
22781 }
22782
22785 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22786 {
22787 if (compares_unordered(lhs, rhs, true))
22788 {
22789 return false;
22790 }
22791 return !(rhs < lhs);
22792 }
22793
22796 template<typename ScalarType, typename std::enable_if<
22797 std::is_scalar<ScalarType>::value, int>::type = 0>
22798 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
22799 {
22800 return lhs <= basic_json(rhs);
22801 }
22802
22805 template<typename ScalarType, typename std::enable_if<
22806 std::is_scalar<ScalarType>::value, int>::type = 0>
22807 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
22808 {
22809 return basic_json(lhs) <= rhs;
22810 }
22811
22814 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22815 {
22816 // double inverse
22817 if (compares_unordered(lhs, rhs))
22818 {
22819 return false;
22820 }
22821 return !(lhs <= rhs);
22822 }
22823
22826 template<typename ScalarType, typename std::enable_if<
22827 std::is_scalar<ScalarType>::value, int>::type = 0>
22828 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
22829 {
22830 return lhs > basic_json(rhs);
22831 }
22832
22835 template<typename ScalarType, typename std::enable_if<
22836 std::is_scalar<ScalarType>::value, int>::type = 0>
22837 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
22838 {
22839 return basic_json(lhs) > rhs;
22840 }
22841
22844 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22845 {
22846 if (compares_unordered(lhs, rhs, true))
22847 {
22848 return false;
22849 }
22850 return !(lhs < rhs);
22851 }
22852
22855 template<typename ScalarType, typename std::enable_if<
22856 std::is_scalar<ScalarType>::value, int>::type = 0>
22857 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
22858 {
22859 return lhs >= basic_json(rhs);
22860 }
22861
22864 template<typename ScalarType, typename std::enable_if<
22865 std::is_scalar<ScalarType>::value, int>::type = 0>
22866 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
22867 {
22868 return basic_json(lhs) >= rhs;
22869 }
22870#endif
22871
22872#undef JSON_IMPLEMENT_OPERATOR
22873
22875
22877 // serialization //
22879
22882#ifndef JSON_NO_IO
22885 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
22886 {
22887 // read width member and use it as indentation parameter if nonzero
22888 const bool pretty_print = o.width() > 0;
22889 const auto indentation = pretty_print ? o.width() : 0;
22890
22891 // reset width to 0 for subsequent calls to this stream
22892 o.width(0);
22893
22894 // do the actual serialization
22895 serializer s(detail::output_adapter<char>(o), o.fill());
22896 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
22897 return o;
22898 }
22899
22906 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
22907 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
22908 {
22909 return o << j;
22910 }
22911#endif // JSON_NO_IO
22913
22914
22916 // deserialization //
22918
22921
22924 template<typename InputType>
22926 static basic_json parse(InputType&& i,
22927 const parser_callback_t cb = nullptr,
22928 const bool allow_exceptions = true,
22929 const bool ignore_comments = false)
22930 {
22931 basic_json result;
22932 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
22933 return result;
22934 }
22935
22938 template<typename IteratorType>
22940 static basic_json parse(IteratorType first,
22941 IteratorType last,
22942 const parser_callback_t cb = nullptr,
22943 const bool allow_exceptions = true,
22944 const bool ignore_comments = false)
22945 {
22946 basic_json result;
22947 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
22948 return result;
22949 }
22950
22952 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
22953 static basic_json parse(detail::span_input_adapter&& i,
22954 const parser_callback_t cb = nullptr,
22955 const bool allow_exceptions = true,
22956 const bool ignore_comments = false)
22957 {
22958 basic_json result;
22959 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
22960 return result;
22961 }
22962
22965 template<typename InputType>
22966 static bool accept(InputType&& i,
22967 const bool ignore_comments = false)
22968 {
22969 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
22970 }
22971
22974 template<typename IteratorType>
22975 static bool accept(IteratorType first, IteratorType last,
22976 const bool ignore_comments = false)
22977 {
22978 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
22979 }
22980
22982 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
22983 static bool accept(detail::span_input_adapter&& i,
22984 const bool ignore_comments = false)
22985 {
22986 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
22987 }
22988
22991 template <typename InputType, typename SAX>
22993 static bool sax_parse(InputType&& i, SAX* sax,
22995 const bool strict = true,
22996 const bool ignore_comments = false)
22997 {
22998 auto ia = detail::input_adapter(std::forward<InputType>(i));
22999 return format == input_format_t::json
23000 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23001 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23002 }
23003
23006 template<class IteratorType, class SAX>
23008 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23010 const bool strict = true,
23011 const bool ignore_comments = false)
23012 {
23013 auto ia = detail::input_adapter(std::move(first), std::move(last));
23014 return format == input_format_t::json
23015 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23016 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23017 }
23018
23024 template <typename SAX>
23025 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23027 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23029 const bool strict = true,
23030 const bool ignore_comments = false)
23031 {
23032 auto ia = i.get();
23033 return format == input_format_t::json
23034 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23035 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23036 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23037 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23038 }
23039#ifndef JSON_NO_IO
23046 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23047 friend std::istream& operator<<(basic_json& j, std::istream& i)
23048 {
23049 return operator>>(i, j);
23050 }
23051
23054 friend std::istream& operator>>(std::istream& i, basic_json& j)
23055 {
23056 parser(detail::input_adapter(i)).parse(false, j);
23057 return i;
23058 }
23059#endif // JSON_NO_IO
23061
23063 // convenience functions //
23065
23069 const char* type_name() const noexcept
23070 {
23071 switch (m_type)
23072 {
23073 case value_t::null:
23074 return "null";
23075 case value_t::object:
23076 return "object";
23077 case value_t::array:
23078 return "array";
23079 case value_t::string:
23080 return "string";
23081 case value_t::boolean:
23082 return "boolean";
23083 case value_t::binary:
23084 return "binary";
23085 case value_t::discarded:
23086 return "discarded";
23087 case value_t::number_integer:
23088 case value_t::number_unsigned:
23089 case value_t::number_float:
23090 default:
23091 return "number";
23092 }
23093 }
23094
23095
23098 // member variables //
23100
23102 value_t m_type = value_t::null;
23103
23105 json_value m_value = {};
23106
23107#if JSON_DIAGNOSTICS
23109 basic_json* m_parent = nullptr;
23110#endif
23111
23113 // binary serialization/deserialization //
23115
23118
23119 public:
23122 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
23123 {
23124 std::vector<std::uint8_t> result;
23125 to_cbor(j, result);
23126 return result;
23127 }
23128
23132 {
23133 binary_writer<std::uint8_t>(o).write_cbor(j);
23134 }
23135
23139 {
23140 binary_writer<char>(o).write_cbor(j);
23141 }
23142
23145 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
23146 {
23147 std::vector<std::uint8_t> result;
23148 to_msgpack(j, result);
23149 return result;
23150 }
23151
23155 {
23156 binary_writer<std::uint8_t>(o).write_msgpack(j);
23157 }
23158
23162 {
23163 binary_writer<char>(o).write_msgpack(j);
23164 }
23165
23168 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
23169 const bool use_size = false,
23170 const bool use_type = false)
23171 {
23172 std::vector<std::uint8_t> result;
23173 to_ubjson(j, result, use_size, use_type);
23174 return result;
23175 }
23176
23180 const bool use_size = false, const bool use_type = false)
23181 {
23182 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
23183 }
23184
23188 const bool use_size = false, const bool use_type = false)
23189 {
23190 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23191 }
23192
23195 static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
23196 const bool use_size = false,
23197 const bool use_type = false)
23198 {
23199 std::vector<std::uint8_t> result;
23200 to_bjdata(j, result, use_size, use_type);
23201 return result;
23202 }
23203
23207 const bool use_size = false, const bool use_type = false)
23208 {
23209 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
23210 }
23211
23215 const bool use_size = false, const bool use_type = false)
23216 {
23217 binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
23218 }
23219
23222 static std::vector<std::uint8_t> to_bson(const basic_json& j)
23223 {
23224 std::vector<std::uint8_t> result;
23225 to_bson(j, result);
23226 return result;
23227 }
23228
23232 {
23233 binary_writer<std::uint8_t>(o).write_bson(j);
23234 }
23235
23239 {
23240 binary_writer<char>(o).write_bson(j);
23241 }
23242
23245 template<typename InputType>
23247 static basic_json from_cbor(InputType&& i,
23248 const bool strict = true,
23249 const bool allow_exceptions = true,
23250 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23251 {
23252 basic_json result;
23253 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23254 auto ia = detail::input_adapter(std::forward<InputType>(i));
23255 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23256 return res ? result : basic_json(value_t::discarded);
23257 }
23258
23261 template<typename IteratorType>
23263 static basic_json from_cbor(IteratorType first, IteratorType last,
23264 const bool strict = true,
23265 const bool allow_exceptions = true,
23266 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23267 {
23268 basic_json result;
23269 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23270 auto ia = detail::input_adapter(std::move(first), std::move(last));
23271 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23272 return res ? result : basic_json(value_t::discarded);
23273 }
23274
23275 template<typename T>
23277 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23278 static basic_json from_cbor(const T* ptr, std::size_t len,
23279 const bool strict = true,
23280 const bool allow_exceptions = true,
23281 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23282 {
23283 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23284 }
23285
23286
23288 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23289 static basic_json from_cbor(detail::span_input_adapter&& i,
23290 const bool strict = true,
23291 const bool allow_exceptions = true,
23292 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23293 {
23294 basic_json result;
23295 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23296 auto ia = i.get();
23297 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23298 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23299 return res ? result : basic_json(value_t::discarded);
23300 }
23301
23304 template<typename InputType>
23306 static basic_json from_msgpack(InputType&& i,
23307 const bool strict = true,
23308 const bool allow_exceptions = true)
23309 {
23310 basic_json result;
23311 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23312 auto ia = detail::input_adapter(std::forward<InputType>(i));
23313 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23314 return res ? result : basic_json(value_t::discarded);
23315 }
23316
23319 template<typename IteratorType>
23321 static basic_json from_msgpack(IteratorType first, IteratorType last,
23322 const bool strict = true,
23323 const bool allow_exceptions = true)
23324 {
23325 basic_json result;
23326 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23327 auto ia = detail::input_adapter(std::move(first), std::move(last));
23328 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23329 return res ? result : basic_json(value_t::discarded);
23330 }
23331
23332 template<typename T>
23334 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23335 static basic_json from_msgpack(const T* ptr, std::size_t len,
23336 const bool strict = true,
23337 const bool allow_exceptions = true)
23338 {
23339 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23340 }
23341
23343 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23344 static basic_json from_msgpack(detail::span_input_adapter&& i,
23345 const bool strict = true,
23346 const bool allow_exceptions = true)
23347 {
23348 basic_json result;
23349 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23350 auto ia = i.get();
23351 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23352 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23353 return res ? result : basic_json(value_t::discarded);
23354 }
23355
23358 template<typename InputType>
23360 static basic_json from_ubjson(InputType&& i,
23361 const bool strict = true,
23362 const bool allow_exceptions = true)
23363 {
23364 basic_json result;
23365 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23366 auto ia = detail::input_adapter(std::forward<InputType>(i));
23367 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23368 return res ? result : basic_json(value_t::discarded);
23369 }
23370
23373 template<typename IteratorType>
23375 static basic_json from_ubjson(IteratorType first, IteratorType last,
23376 const bool strict = true,
23377 const bool allow_exceptions = true)
23378 {
23379 basic_json result;
23380 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23381 auto ia = detail::input_adapter(std::move(first), std::move(last));
23382 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23383 return res ? result : basic_json(value_t::discarded);
23384 }
23385
23386 template<typename T>
23388 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23389 static basic_json from_ubjson(const T* ptr, std::size_t len,
23390 const bool strict = true,
23391 const bool allow_exceptions = true)
23392 {
23393 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23394 }
23395
23397 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23398 static basic_json from_ubjson(detail::span_input_adapter&& i,
23399 const bool strict = true,
23400 const bool allow_exceptions = true)
23401 {
23402 basic_json result;
23403 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23404 auto ia = i.get();
23405 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23406 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23407 return res ? result : basic_json(value_t::discarded);
23408 }
23409
23410
23413 template<typename InputType>
23415 static basic_json from_bjdata(InputType&& i,
23416 const bool strict = true,
23417 const bool allow_exceptions = true)
23418 {
23419 basic_json result;
23420 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23421 auto ia = detail::input_adapter(std::forward<InputType>(i));
23422 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23423 return res ? result : basic_json(value_t::discarded);
23424 }
23425
23428 template<typename IteratorType>
23430 static basic_json from_bjdata(IteratorType first, IteratorType last,
23431 const bool strict = true,
23432 const bool allow_exceptions = true)
23433 {
23434 basic_json result;
23435 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23436 auto ia = detail::input_adapter(std::move(first), std::move(last));
23437 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23438 return res ? result : basic_json(value_t::discarded);
23439 }
23440
23443 template<typename InputType>
23445 static basic_json from_bson(InputType&& i,
23446 const bool strict = true,
23447 const bool allow_exceptions = true)
23448 {
23449 basic_json result;
23450 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23451 auto ia = detail::input_adapter(std::forward<InputType>(i));
23452 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23453 return res ? result : basic_json(value_t::discarded);
23454 }
23455
23458 template<typename IteratorType>
23460 static basic_json from_bson(IteratorType first, IteratorType last,
23461 const bool strict = true,
23462 const bool allow_exceptions = true)
23463 {
23464 basic_json result;
23465 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23466 auto ia = detail::input_adapter(std::move(first), std::move(last));
23467 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23468 return res ? result : basic_json(value_t::discarded);
23469 }
23470
23471 template<typename T>
23473 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23474 static basic_json from_bson(const T* ptr, std::size_t len,
23475 const bool strict = true,
23476 const bool allow_exceptions = true)
23477 {
23478 return from_bson(ptr, ptr + len, strict, allow_exceptions);
23479 }
23480
23482 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23483 static basic_json from_bson(detail::span_input_adapter&& i,
23484 const bool strict = true,
23485 const bool allow_exceptions = true)
23486 {
23487 basic_json result;
23488 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23489 auto ia = i.get();
23490 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23491 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23492 return res ? result : basic_json(value_t::discarded);
23493 }
23495
23497 // JSON Pointer support //
23499
23502
23506 {
23507 return ptr.get_unchecked(this);
23508 }
23509
23510 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23511 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23512 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23513 {
23514 return ptr.get_unchecked(this);
23515 }
23516
23520 {
23521 return ptr.get_unchecked(this);
23522 }
23523
23524 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23525 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23526 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23527 {
23528 return ptr.get_unchecked(this);
23529 }
23530
23533 reference at(const json_pointer& ptr)
23534 {
23535 return ptr.get_checked(this);
23536 }
23537
23538 template<typename BasicJsonType>
23539 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23540 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23541 {
23542 return ptr.get_checked(this);
23543 }
23544
23548 {
23549 return ptr.get_checked(this);
23550 }
23551
23552 template<typename BasicJsonType>
23553 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23554 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23555 {
23556 return ptr.get_checked(this);
23557 }
23558
23561 basic_json flatten() const
23562 {
23563 basic_json result(value_t::object);
23564 json_pointer::flatten("", *this, result);
23565 return result;
23566 }
23567
23570 basic_json unflatten() const
23571 {
23572 return json_pointer::unflatten(*this);
23573 }
23574
23576
23578 // JSON Patch functions //
23580
23583
23586 void patch_inplace(const basic_json& json_patch)
23587 {
23588 basic_json& result = *this;
23589 // the valid JSON Patch operations
23590 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23591
23592 const auto get_op = [](const std::string & op)
23593 {
23594 if (op == "add")
23595 {
23596 return patch_operations::add;
23597 }
23598 if (op == "remove")
23599 {
23600 return patch_operations::remove;
23601 }
23602 if (op == "replace")
23603 {
23604 return patch_operations::replace;
23605 }
23606 if (op == "move")
23607 {
23608 return patch_operations::move;
23609 }
23610 if (op == "copy")
23611 {
23612 return patch_operations::copy;
23613 }
23614 if (op == "test")
23615 {
23616 return patch_operations::test;
23617 }
23618
23619 return patch_operations::invalid;
23620 };
23621
23622 // wrapper for "add" operation; add value at ptr
23623 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
23624 {
23625 // adding to the root of the target document means replacing it
23626 if (ptr.empty())
23627 {
23628 result = val;
23629 return;
23630 }
23631
23632 // make sure the top element of the pointer exists
23633 json_pointer top_pointer = ptr.top();
23634 if (top_pointer != ptr)
23635 {
23636 result.at(top_pointer);
23637 }
23638
23639 // get reference to parent of JSON pointer ptr
23640 const auto last_path = ptr.back();
23641 ptr.pop_back();
23642 // parent must exist when performing patch add per RFC6902 specs
23643 basic_json& parent = result.at(ptr);
23644
23645 switch (parent.m_type)
23646 {
23647 case value_t::null:
23648 case value_t::object:
23649 {
23650 // use operator[] to add value
23651 parent[last_path] = val;
23652 break;
23653 }
23654
23655 case value_t::array:
23656 {
23657 if (last_path == "-")
23658 {
23659 // special case: append to back
23660 parent.push_back(val);
23661 }
23662 else
23663 {
23664 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
23665 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
23666 {
23667 // avoid undefined behavior
23668 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
23669 }
23670
23671 // default case: insert add offset
23672 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
23673 }
23674 break;
23675 }
23676
23677 // if there exists a parent it cannot be primitive
23678 case value_t::string: // LCOV_EXCL_LINE
23679 case value_t::boolean: // LCOV_EXCL_LINE
23680 case value_t::number_integer: // LCOV_EXCL_LINE
23681 case value_t::number_unsigned: // LCOV_EXCL_LINE
23682 case value_t::number_float: // LCOV_EXCL_LINE
23683 case value_t::binary: // LCOV_EXCL_LINE
23684 case value_t::discarded: // LCOV_EXCL_LINE
23685 default: // LCOV_EXCL_LINE
23686 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
23687 }
23688 };
23689
23690 // wrapper for "remove" operation; remove value at ptr
23691 const auto operation_remove = [this, &result](json_pointer & ptr)
23692 {
23693 // get reference to parent of JSON pointer ptr
23694 const auto last_path = ptr.back();
23695 ptr.pop_back();
23696 basic_json& parent = result.at(ptr);
23697
23698 // remove child
23699 if (parent.is_object())
23700 {
23701 // perform range check
23702 auto it = parent.find(last_path);
23703 if (JSON_HEDLEY_LIKELY(it != parent.end()))
23704 {
23705 parent.erase(it);
23706 }
23707 else
23708 {
23709 JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
23710 }
23711 }
23712 else if (parent.is_array())
23713 {
23714 // note erase performs range check
23715 parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
23716 }
23717 };
23718
23719 // type check: top level value must be an array
23720 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
23721 {
23722 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
23723 }
23724
23725 // iterate and apply the operations
23726 for (const auto& val : json_patch)
23727 {
23728 // wrapper to get a value for an operation
23729 const auto get_value = [&val](const std::string & op,
23730 const std::string & member,
23731 bool string_type) -> basic_json &
23732 {
23733 // find value
23734 auto it = val.m_value.object->find(member);
23735
23736 // context-sensitive error message
23737 const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
23738
23739 // check if desired value is present
23740 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
23741 {
23742 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
23743 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
23744 }
23745
23746 // check if result is of type string
23747 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
23748 {
23749 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
23750 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
23751 }
23752
23753 // no error: return value
23754 return it->second;
23755 };
23756
23757 // type check: every element of the array must be an object
23758 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
23759 {
23760 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
23761 }
23762
23763 // collect mandatory members
23764 const auto op = get_value("op", "op", true).template get<std::string>();
23765 const auto path = get_value(op, "path", true).template get<std::string>();
23766 json_pointer ptr(path);
23767
23768 switch (get_op(op))
23769 {
23770 case patch_operations::add:
23771 {
23772 operation_add(ptr, get_value("add", "value", false));
23773 break;
23774 }
23775
23776 case patch_operations::remove:
23777 {
23778 operation_remove(ptr);
23779 break;
23780 }
23781
23782 case patch_operations::replace:
23783 {
23784 // the "path" location must exist - use at()
23785 result.at(ptr) = get_value("replace", "value", false);
23786 break;
23787 }
23788
23789 case patch_operations::move:
23790 {
23791 const auto from_path = get_value("move", "from", true).template get<std::string>();
23792 json_pointer from_ptr(from_path);
23793
23794 // the "from" location must exist - use at()
23795 basic_json v = result.at(from_ptr);
23796
23797 // The move operation is functionally identical to a
23798 // "remove" operation on the "from" location, followed
23799 // immediately by an "add" operation at the target
23800 // location with the value that was just removed.
23801 operation_remove(from_ptr);
23802 operation_add(ptr, v);
23803 break;
23804 }
23805
23806 case patch_operations::copy:
23807 {
23808 const auto from_path = get_value("copy", "from", true).template get<std::string>();
23809 const json_pointer from_ptr(from_path);
23810
23811 // the "from" location must exist - use at()
23812 basic_json v = result.at(from_ptr);
23813
23814 // The copy is functionally identical to an "add"
23815 // operation at the target location using the value
23816 // specified in the "from" member.
23817 operation_add(ptr, v);
23818 break;
23819 }
23820
23821 case patch_operations::test:
23822 {
23823 bool success = false;
23824 JSON_TRY
23825 {
23826 // check if "value" matches the one at "path"
23827 // the "path" location must exist - use at()
23828 success = (result.at(ptr) == get_value("test", "value", false));
23829 }
23830 JSON_INTERNAL_CATCH (out_of_range&)
23831 {
23832 // ignore out of range errors: success remains false
23833 }
23834
23835 // throw an exception if test fails
23836 if (JSON_HEDLEY_UNLIKELY(!success))
23837 {
23838 JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
23839 }
23840
23841 break;
23842 }
23843
23844 case patch_operations::invalid:
23845 default:
23846 {
23847 // op must be "add", "remove", "replace", "move", "copy", or
23848 // "test"
23849 JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
23850 }
23851 }
23852 }
23853 }
23854
23857 basic_json patch(const basic_json& json_patch) const
23858 {
23859 basic_json result = *this;
23860 result.patch_inplace(json_patch);
23861 return result;
23862 }
23863
23867 static basic_json diff(const basic_json& source, const basic_json& target,
23868 const std::string& path = "")
23869 {
23870 // the patch
23871 basic_json result(value_t::array);
23872
23873 // if the values are the same, return empty patch
23874 if (source == target)
23875 {
23876 return result;
23877 }
23878
23879 if (source.type() != target.type())
23880 {
23881 // different types: replace value
23882 result.push_back(
23883 {
23884 {"op", "replace"}, {"path", path}, {"value", target}
23885 });
23886 return result;
23887 }
23888
23889 switch (source.type())
23890 {
23891 case value_t::array:
23892 {
23893 // first pass: traverse common elements
23894 std::size_t i = 0;
23895 while (i < source.size() && i < target.size())
23896 {
23897 // recursive call to compare array values at index i
23898 auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
23899 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
23900 ++i;
23901 }
23902
23903 // We now reached the end of at least one array
23904 // in a second pass, traverse the remaining elements
23905
23906 // remove my remaining elements
23907 const auto end_index = static_cast<difference_type>(result.size());
23908 while (i < source.size())
23909 {
23910 // add operations in reverse order to avoid invalid
23911 // indices
23912 result.insert(result.begin() + end_index, object(
23913 {
23914 {"op", "remove"},
23915 {"path", detail::concat(path, '/', std::to_string(i))}
23916 }));
23917 ++i;
23918 }
23919
23920 // add other remaining elements
23921 while (i < target.size())
23922 {
23923 result.push_back(
23924 {
23925 {"op", "add"},
23926 {"path", detail::concat(path, "/-")},
23927 {"value", target[i]}
23928 });
23929 ++i;
23930 }
23931
23932 break;
23933 }
23934
23935 case value_t::object:
23936 {
23937 // first pass: traverse this object's elements
23938 for (auto it = source.cbegin(); it != source.cend(); ++it)
23939 {
23940 // escape the key name to be used in a JSON patch
23941 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23942
23943 if (target.find(it.key()) != target.end())
23944 {
23945 // recursive call to compare object values at key it
23946 auto temp_diff = diff(it.value(), target[it.key()], path_key);
23947 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
23948 }
23949 else
23950 {
23951 // found a key that is not in o -> remove it
23952 result.push_back(object(
23953 {
23954 {"op", "remove"}, {"path", path_key}
23955 }));
23956 }
23957 }
23958
23959 // second pass: traverse other object's elements
23960 for (auto it = target.cbegin(); it != target.cend(); ++it)
23961 {
23962 if (source.find(it.key()) == source.end())
23963 {
23964 // found a key that is not in this -> add it
23965 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23966 result.push_back(
23967 {
23968 {"op", "add"}, {"path", path_key},
23969 {"value", it.value()}
23970 });
23971 }
23972 }
23973
23974 break;
23975 }
23976
23977 case value_t::null:
23978 case value_t::string:
23979 case value_t::boolean:
23980 case value_t::number_integer:
23981 case value_t::number_unsigned:
23982 case value_t::number_float:
23983 case value_t::binary:
23984 case value_t::discarded:
23985 default:
23986 {
23987 // both primitive type: replace value
23988 result.push_back(
23989 {
23990 {"op", "replace"}, {"path", path}, {"value", target}
23991 });
23992 break;
23993 }
23994 }
23995
23996 return result;
23997 }
23999
24001 // JSON Merge Patch functions //
24003
24006
24009 void merge_patch(const basic_json& apply_patch)
24010 {
24011 if (apply_patch.is_object())
24012 {
24013 if (!is_object())
24014 {
24015 *this = object();
24016 }
24017 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24018 {
24019 if (it.value().is_null())
24020 {
24021 erase(it.key());
24022 }
24023 else
24024 {
24025 operator[](it.key()).merge_patch(it.value());
24026 }
24027 }
24028 }
24029 else
24030 {
24031 *this = apply_patch;
24032 }
24033 }
24034
24036};
24037
24042{
24043 return j.dump();
24044}
24045
24046inline namespace literals
24047{
24048inline namespace json_literals
24049{
24050
24054inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24055{
24056 return nlohmann::json::parse(s, s + n);
24057}
24058
24062inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24063{
24064 return nlohmann::json::json_pointer(std::string(s, n));
24065}
24066
24067} // namespace json_literals
24068} // namespace literals
24070
24072// nonmember support //
24074
24075namespace std // NOLINT(cert-dcl58-cpp)
24076{
24077
24082{
24084 {
24085 return nlohmann::detail::hash(j);
24086 }
24087};
24088
24089// specialization for std::less<value_t>
24090template<>
24091struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
24092{
24098 ::nlohmann::detail::value_t rhs) const noexcept
24099 {
24100#if JSON_HAS_THREE_WAY_COMPARISON
24101 return std::is_lt(lhs <=> rhs); // *NOPAD*
24102#else
24104#endif
24105 }
24106};
24107
24108// C++20 prohibit function specialization in the std namespace.
24109#ifndef JSON_HAS_CPP_20
24110
24114inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
24115 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
24116 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
24117{
24118 j1.swap(j2);
24119}
24120
24121#endif
24122
24123} // namespace std
24124
24125#if JSON_USE_GLOBAL_UDLS
24126 using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24127 using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24128#endif
24129
24130// #include <nlohmann/detail/macro_unscope.hpp>
24131// __ _____ _____ _____
24132// __| | __| | | | JSON for Modern C++
24133// | | |__ | | | | | | version 3.11.1
24134// |_____|_____|_____|_|___| https://github.com/nlohmann/json
24135//
24136// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24137// SPDX-License-Identifier: MIT
24138
24139
24140
24141// restore clang diagnostic settings
24142#if defined(__clang__)
24143 #pragma clang diagnostic pop
24144#endif
24145
24146// clean up
24147#undef JSON_ASSERT
24148#undef JSON_INTERNAL_CATCH
24149#undef JSON_THROW
24150#undef JSON_PRIVATE_UNLESS_TESTED
24151#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24152#undef NLOHMANN_BASIC_JSON_TPL
24153#undef JSON_EXPLICIT
24154#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
24155#undef JSON_INLINE_VARIABLE
24156#undef JSON_NO_UNIQUE_ADDRESS
24157#undef JSON_DISABLE_ENUM_SERIALIZATION
24158#undef JSON_USE_GLOBAL_UDLS
24159
24160#ifndef JSON_TEST_KEEP_MACROS
24161 #undef JSON_CATCH
24162 #undef JSON_TRY
24163 #undef JSON_HAS_CPP_11
24164 #undef JSON_HAS_CPP_14
24165 #undef JSON_HAS_CPP_17
24166 #undef JSON_HAS_CPP_20
24167 #undef JSON_HAS_FILESYSTEM
24168 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
24169 #undef JSON_HAS_THREE_WAY_COMPARISON
24170 #undef JSON_HAS_RANGES
24171 #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
24172#endif
24173
24174// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24175// __ _____ _____ _____
24176// __| | __| | | | JSON for Modern C++
24177// | | |__ | | | | | | version 3.11.1
24178// |_____|_____|_____|_|___| https://github.com/nlohmann/json
24179//
24180// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24181// SPDX-License-Identifier: MIT
24182
24183
24184
24185#undef JSON_HEDLEY_ALWAYS_INLINE
24186#undef JSON_HEDLEY_ARM_VERSION
24187#undef JSON_HEDLEY_ARM_VERSION_CHECK
24188#undef JSON_HEDLEY_ARRAY_PARAM
24189#undef JSON_HEDLEY_ASSUME
24190#undef JSON_HEDLEY_BEGIN_C_DECLS
24191#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24192#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24193#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24194#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24195#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24196#undef JSON_HEDLEY_CLANG_HAS_FEATURE
24197#undef JSON_HEDLEY_CLANG_HAS_WARNING
24198#undef JSON_HEDLEY_COMPCERT_VERSION
24199#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24200#undef JSON_HEDLEY_CONCAT
24201#undef JSON_HEDLEY_CONCAT3
24202#undef JSON_HEDLEY_CONCAT3_EX
24203#undef JSON_HEDLEY_CONCAT_EX
24204#undef JSON_HEDLEY_CONST
24205#undef JSON_HEDLEY_CONSTEXPR
24206#undef JSON_HEDLEY_CONST_CAST
24207#undef JSON_HEDLEY_CPP_CAST
24208#undef JSON_HEDLEY_CRAY_VERSION
24209#undef JSON_HEDLEY_CRAY_VERSION_CHECK
24210#undef JSON_HEDLEY_C_DECL
24211#undef JSON_HEDLEY_DEPRECATED
24212#undef JSON_HEDLEY_DEPRECATED_FOR
24213#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24214#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24215#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24216#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24217#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24218#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
24219#undef JSON_HEDLEY_DIAGNOSTIC_POP
24220#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24221#undef JSON_HEDLEY_DMC_VERSION
24222#undef JSON_HEDLEY_DMC_VERSION_CHECK
24223#undef JSON_HEDLEY_EMPTY_BASES
24224#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24225#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24226#undef JSON_HEDLEY_END_C_DECLS
24227#undef JSON_HEDLEY_FLAGS
24228#undef JSON_HEDLEY_FLAGS_CAST
24229#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24230#undef JSON_HEDLEY_GCC_HAS_BUILTIN
24231#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24232#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24233#undef JSON_HEDLEY_GCC_HAS_EXTENSION
24234#undef JSON_HEDLEY_GCC_HAS_FEATURE
24235#undef JSON_HEDLEY_GCC_HAS_WARNING
24236#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24237#undef JSON_HEDLEY_GCC_VERSION
24238#undef JSON_HEDLEY_GCC_VERSION_CHECK
24239#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24240#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24241#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24242#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24243#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24244#undef JSON_HEDLEY_GNUC_HAS_FEATURE
24245#undef JSON_HEDLEY_GNUC_HAS_WARNING
24246#undef JSON_HEDLEY_GNUC_VERSION
24247#undef JSON_HEDLEY_GNUC_VERSION_CHECK
24248#undef JSON_HEDLEY_HAS_ATTRIBUTE
24249#undef JSON_HEDLEY_HAS_BUILTIN
24250#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24251#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24252#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24253#undef JSON_HEDLEY_HAS_EXTENSION
24254#undef JSON_HEDLEY_HAS_FEATURE
24255#undef JSON_HEDLEY_HAS_WARNING
24256#undef JSON_HEDLEY_IAR_VERSION
24257#undef JSON_HEDLEY_IAR_VERSION_CHECK
24258#undef JSON_HEDLEY_IBM_VERSION
24259#undef JSON_HEDLEY_IBM_VERSION_CHECK
24260#undef JSON_HEDLEY_IMPORT
24261#undef JSON_HEDLEY_INLINE
24262#undef JSON_HEDLEY_INTEL_CL_VERSION
24263#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
24264#undef JSON_HEDLEY_INTEL_VERSION
24265#undef JSON_HEDLEY_INTEL_VERSION_CHECK
24266#undef JSON_HEDLEY_IS_CONSTANT
24267#undef JSON_HEDLEY_IS_CONSTEXPR_
24268#undef JSON_HEDLEY_LIKELY
24269#undef JSON_HEDLEY_MALLOC
24270#undef JSON_HEDLEY_MCST_LCC_VERSION
24271#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
24272#undef JSON_HEDLEY_MESSAGE
24273#undef JSON_HEDLEY_MSVC_VERSION
24274#undef JSON_HEDLEY_MSVC_VERSION_CHECK
24275#undef JSON_HEDLEY_NEVER_INLINE
24276#undef JSON_HEDLEY_NON_NULL
24277#undef JSON_HEDLEY_NO_ESCAPE
24278#undef JSON_HEDLEY_NO_RETURN
24279#undef JSON_HEDLEY_NO_THROW
24280#undef JSON_HEDLEY_NULL
24281#undef JSON_HEDLEY_PELLES_VERSION
24282#undef JSON_HEDLEY_PELLES_VERSION_CHECK
24283#undef JSON_HEDLEY_PGI_VERSION
24284#undef JSON_HEDLEY_PGI_VERSION_CHECK
24285#undef JSON_HEDLEY_PREDICT
24286#undef JSON_HEDLEY_PRINTF_FORMAT
24287#undef JSON_HEDLEY_PRIVATE
24288#undef JSON_HEDLEY_PUBLIC
24289#undef JSON_HEDLEY_PURE
24290#undef JSON_HEDLEY_REINTERPRET_CAST
24291#undef JSON_HEDLEY_REQUIRE
24292#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24293#undef JSON_HEDLEY_REQUIRE_MSG
24294#undef JSON_HEDLEY_RESTRICT
24295#undef JSON_HEDLEY_RETURNS_NON_NULL
24296#undef JSON_HEDLEY_SENTINEL
24297#undef JSON_HEDLEY_STATIC_ASSERT
24298#undef JSON_HEDLEY_STATIC_CAST
24299#undef JSON_HEDLEY_STRINGIFY
24300#undef JSON_HEDLEY_STRINGIFY_EX
24301#undef JSON_HEDLEY_SUNPRO_VERSION
24302#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24303#undef JSON_HEDLEY_TINYC_VERSION
24304#undef JSON_HEDLEY_TINYC_VERSION_CHECK
24305#undef JSON_HEDLEY_TI_ARMCL_VERSION
24306#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24307#undef JSON_HEDLEY_TI_CL2000_VERSION
24308#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24309#undef JSON_HEDLEY_TI_CL430_VERSION
24310#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24311#undef JSON_HEDLEY_TI_CL6X_VERSION
24312#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24313#undef JSON_HEDLEY_TI_CL7X_VERSION
24314#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24315#undef JSON_HEDLEY_TI_CLPRU_VERSION
24316#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24317#undef JSON_HEDLEY_TI_VERSION
24318#undef JSON_HEDLEY_TI_VERSION_CHECK
24319#undef JSON_HEDLEY_UNAVAILABLE
24320#undef JSON_HEDLEY_UNLIKELY
24321#undef JSON_HEDLEY_UNPREDICTABLE
24322#undef JSON_HEDLEY_UNREACHABLE
24323#undef JSON_HEDLEY_UNREACHABLE_RETURN
24324#undef JSON_HEDLEY_VERSION
24325#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24326#undef JSON_HEDLEY_VERSION_DECODE_MINOR
24327#undef JSON_HEDLEY_VERSION_DECODE_REVISION
24328#undef JSON_HEDLEY_VERSION_ENCODE
24329#undef JSON_HEDLEY_WARNING
24330#undef JSON_HEDLEY_WARN_UNUSED_RESULT
24331#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
24332#undef JSON_HEDLEY_FALL_THROUGH
24333
24334
24335
24336#endif // INCLUDE_NLOHMANN_JSON_HPP_
namespace for Niels Lohmann
Definition: json.hpp:19065
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:19347
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22086
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: json.hpp:19515
void destroy(value_t t)
Definition: json.hpp:19523
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22023
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:23460
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21628
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:19939
std::decay< ValueType >::type value(const KeyType &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:21173
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:19215
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:19961
void set_parents()
Definition: json.hpp:19662
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:21652
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21528
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22031
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:19969
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.hpp:19119
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23122
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19989
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:20250
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:19761
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21405
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: json.hpp:19518
const_reference operator[](T *key) const
Definition: json.hpp:21120
number_float_t number_float
number (floating-point)
Definition: json.hpp:19409
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:19207
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:19414
const_reference back() const
access the last element
Definition: json.hpp:21323
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24009
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:22222
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20408
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:19330
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20512
void swap(object_t &other)
exchanges the values
Definition: json.hpp:22417
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:19139
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20501
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:20390
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:22449
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:20754
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:21076
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition: json.hpp:20652
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:19191
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference operator[](const
Definition: json.hpp:23511
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:19194
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) ValueType value(const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21275
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.hpp:20604
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:19200
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23195
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22325
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23505
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:19181
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:21521
basic_json(const JsonRef &ref)
Definition: json.hpp:20099
json_value m_value
the value of the current element
Definition: json.hpp:23105
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20741
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:20372
::nlohmann::detail::json_reverse_iterator< Base > json_reverse_iterator
Definition: json.hpp:19116
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:21636
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:19407
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:22273
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:20396
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20327
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:19500
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:22144
::nlohmann::detail::binary_reader< basic_json, InputType > binary_reader
Definition: json.hpp:19122
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:21604
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:20801
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:20378
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:22195
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:20872
::nlohmann::detail::iteration_proxy< Iterator > iteration_proxy
Definition: json.hpp:19115
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:19186
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23138
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23145
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22063
std::decay< ValueType >::type value(KeyType &&key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:21222
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:19399
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:21645
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22372
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition: json.hpp:23857
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20420
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:21129
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:20384
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:23445
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:20361
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:22215
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:19133
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:20895
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21063
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:23238
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:22465
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition: json.hpp:19097
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20426
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23360
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22176
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19950
string_t value(const typename object_t::key_type &key, const char *default_value) const
access specified object element with default value
Definition: json.hpp:21194
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20271
number_integer_t number_integer
number (integer)
Definition: json.hpp:19405
std::decay< ValueType >::type value(const char *key, ValueType &&default_value) const
Definition: json.hpp:21205
binary_t * binary
binary (stored with pointer to save storage)
Definition: json.hpp:19401
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference at(const
Definition: json.hpp:23539
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23168
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:23069
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:19306
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:19338
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:22293
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21335
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22119
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20790
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:19131
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:19310
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23161
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23321
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20257
StringType string_t
a type for a string
Definition: json.hpp:19314
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20278
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:19509
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23187
json_value()=default
default constructor (for null values)
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:21588
boolean_t boolean
boolean
Definition: json.hpp:19403
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:19422
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23247
const_reference front() const
access the first element
Definition: json.hpp:21307
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:23222
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:19397
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:19494
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:19183
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20320
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:19322
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:20188
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19917
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:21510
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:21572
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21254
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:21558
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:19196
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: json.hpp:20462
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23131
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23263
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:19808
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:23430
::nlohmann::detail::binary_writer< basic_json, CharType > binary_writer
Definition: json.hpp:19123
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23306
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:20918
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19928
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition: json.hpp:19794
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23206
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23519
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) const _reference operator[](const
access specified element via JSON Pointer
Definition: json.hpp:23525
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23214
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20767
::nlohmann::detail::internal_iterator< BasicJsonType > internal_iterator
Definition: json.hpp:19111
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22318
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20414
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20334
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:20171
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21017
binary_t & get_binary()
get a binary value
Definition: json.hpp:20860
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20299
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20306
void swap(string_t &other)
exchanges the values
Definition: json.hpp:22433
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:19334
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.hpp:19090
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:20700
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20450
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:19506
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: json.hpp:19521
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20285
::nlohmann::detail::iter_impl< BasicJsonType > iter_impl
Definition: json.hpp:19113
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:19416
reference operator[](T *key)
Definition: json.hpp:21114
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20341
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:19503
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:20479
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:19189
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21618
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:20228
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:20103
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:19198
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:20778
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:19782
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:20402
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23547
iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
Definition: json.hpp:19699
~basic_json() noexcept
destructor
Definition: json.hpp:20209
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20292
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:19420
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23375
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:19976
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:23231
string_t value(KeyType &&key, const char *default_value) const
access specified object element with default value
Definition: json.hpp:21245
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.hpp:20562
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23179
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23154
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: json.hpp:20456
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22094
reference back()
access the last element
Definition: json.hpp:21314
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20264
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition: json.hpp:19641
reference set_parent(reference j, std::size_t old_capacity=static_cast< std::size_t >(-1))
Definition: json.hpp:19712
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:22110
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: json.hpp:19512
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:23054
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:19418
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:19326
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:19861
string_t value(const char *key, const char *default_value) const
Definition: json.hpp:21210
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:20941
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22389
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:19774
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:20999
void swap(array_t &other)
exchanges the values
Definition: json.hpp:22401
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition: json.hpp:19297
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:22242
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:19318
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20432
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20438
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:19497
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:21098
size_type erase_internal(KeyType &&key)
Definition: json.hpp:21476
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20313
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20665
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition: json.hpp:20629
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:21153
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:22055
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20444
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:20979
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:20961
::nlohmann::detail::primitive_iterator_t primitive_iterator_t
Definition: json.hpp:19109
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:23867
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:23415
an internal type for a backed binary type
Definition: json.hpp:5736
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5776
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5742
std::uint64_t subtype_type
Definition: json.hpp:5739
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5770
BinaryType container_type
Definition: json.hpp:5738
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5764
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5752
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5791
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5757
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5798
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5747
subtype_type m_subtype
Definition: json.hpp:5812
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5783
bool m_has_subtype
Definition: json.hpp:5813
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5805
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9059
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: json.hpp:11823
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result, bool inside_ndarray=false)
determine the type and size for a container
Definition: json.hpp:11223
binary_reader(const binary_reader &)=delete
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: json.hpp:9381
typename BasicJsonType::string_t string_t
Definition: json.hpp:9063
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.hpp:9067
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.hpp:9343
typename InputAdapterType::char_type char_type
Definition: json.hpp:9066
bool parse_msgpack_internal()
Definition: json.hpp:10187
std::string get_token_string() const
Definition: json.hpp:11893
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9061
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.hpp:10568
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.hpp:11906
InputAdapterType ia
input adapter
Definition: json.hpp:11944
bool get_ubjson_high_precision_number()
Definition: json.hpp:11665
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition: json.hpp:11856
binary_reader(binary_reader &&)=default
char_int_type get_ignore_noop()
Definition: json.hpp:11753
bool get_ubjson_value(const char_int_type prefix)
Definition: json.hpp:11291
bool get_ubjson_ndarray_size(std::vector< size_t > &dim)
Definition: json.hpp:10935
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition: json.hpp:9263
bool get_msgpack_object(const std::size_t len)
Definition: json.hpp:10784
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:9075
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9064
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.hpp:9159
binary_reader & operator=(const binary_reader &)=delete
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10131
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: json.hpp:9998
bool get_number(const input_format_t format, NumberType &result)
Definition: json.hpp:11780
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9060
bool get_ubjson_array()
Definition: json.hpp:11474
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.hpp:9184
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:9096
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:10093
bool get_msgpack_array(const std::size_t len)
Definition: json.hpp:10762
char_int_type get()
get next character from the input
Definition: json.hpp:11744
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9062
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: json.hpp:10651
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:10821
SAX json_sax_t
Definition: json.hpp:9065
bool get_ubjson_size_value(std::size_t &result, bool &is_ndarray, char_int_type prefix=0)
Definition: json.hpp:11000
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9411
bool get_ubjson_object()
Definition: json.hpp:11582
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition: json.hpp:9214
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:10840
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.hpp:9902
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition: json.hpp:9236
binary_reader & operator=(binary_reader &&)=default
serialization to CBOR and MessagePack values
Definition: json.hpp:14746
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition: json.hpp:15855
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: json.hpp:15693
void write_bson(const BasicJsonType &j)
Definition: json.hpp:14766
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:14748
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: json.hpp:15753
typename BasicJsonType::string_t string_t
Definition: json.hpp:14747
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16501
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.hpp:15771
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: json.hpp:15836
bool write_bjdata_ndarray(const typename BasicJsonType::object_t &value, const bool use_count, const bool use_type)
Definition: json.hpp:16324
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16508
static constexpr CharType get_cbor_float_prefix(double)
Definition: json.hpp:16001
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: json.hpp:15721
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:14757
static constexpr CharType get_ubjson_float_prefix(double)
Definition: json.hpp:16316
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix, const bool use_bjdata)
Definition: json.hpp:16027
static constexpr CharType get_msgpack_float_prefix(double)
Definition: json.hpp:16015
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: json.hpp:15918
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:16530
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.hpp:15980
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false)
Definition: json.hpp:15445
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: json.hpp:15703
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.hpp:15713
void write_number(const NumberType n, const bool OutputIsLittleEndian=false)
Definition: json.hpp:16451
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition: json.hpp:15666
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.hpp:15735
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:14749
CharType ubjson_prefix(const BasicJsonType &j, const bool use_bjdata) const noexcept
determine the type prefix of container values
Definition: json.hpp:16210
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition: json.hpp:15781
static constexpr CharType get_ubjson_float_prefix(float)
Definition: json.hpp:16311
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: json.hpp:15828
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: json.hpp:15870
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:15119
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: json.hpp:15965
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition: json.hpp:16467
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:14795
static constexpr CharType get_cbor_float_prefix(float)
Definition: json.hpp:15996
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: json.hpp:15681
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: json.hpp:15803
static constexpr CharType get_msgpack_float_prefix(float)
Definition: json.hpp:16010
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.hpp:15813
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.hpp:15743
general exception of the basic_json class
Definition: json.hpp:4223
const int id
the id of the exception
Definition: json.hpp:4232
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4243
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:4315
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4238
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4226
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4249
Definition: json.hpp:6032
char char_type
Definition: json.hpp:6034
file_input_adapter(const file_input_adapter &)=delete
std::FILE * m_file
the file pointer to read from
Definition: json.hpp:6057
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6050
file_input_adapter(file_input_adapter &&) noexcept=default
Definition: json.hpp:6071
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::istream * is
the associated input stream
Definition: json.hpp:6117
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6094
~input_stream_adapter()
Definition: json.hpp:6075
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6104
char char_type
Definition: json.hpp:6073
input_stream_adapter(const input_stream_adapter &)=delete
std::streambuf * sb
Definition: json.hpp:6118
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(std::istream &i)
Definition: json.hpp:6085
exception indicating errors with iterators
Definition: json.hpp:4374
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4377
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12713
~iter_impl()=default
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:13287
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:12850
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:13232
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:12840
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:13179
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:13214
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:13278
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:13093
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:13387
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:13134
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:13031
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13241
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13349
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12743
pointer operator->() const
dereference the iterator
Definition: json.hpp:12989
friend other_iter_impl
allow basic_json to access private members
Definition: json.hpp:12717
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:13412
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:13320
iter_impl(iter_impl &&) noexcept=default
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:12738
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:13298
reference value() const
return the value of an iterator
Definition: json.hpp:13403
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:13223
typename BasicJsonType::array_t array_t
Definition: json.hpp:12723
typename BasicJsonType::object_t object_t
Definition: json.hpp:12722
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:12747
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:13042
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12741
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:12945
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13309
iter_impl()=default
friend BasicJsonType
Definition: json.hpp:12718
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:12825
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:13170
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:13082
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:12752
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:12815
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:12906
Definition: json.hpp:5037
iteration_proxy_value operator++(int) &
Definition: json.hpp:5093
iteration_proxy_value(iteration_proxy_value const &)=default
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5102
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5108
std::ptrdiff_t difference_type
Definition: json.hpp:5039
string_type empty_str
an empty string (to return a reference for primitive values)
Definition: json.hpp:5056
iteration_proxy_value(IteratorType it, std::size_t array_index_=0) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_default_constructible< string_type >::value)
Definition: json.hpp:5060
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5085
std::size_t array_index_last
last stringified array index
Definition: json.hpp:5052
std::size_t array_index
an index for arrays (used to create key names)
Definition: json.hpp:5050
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5150
const string_type & key() const
return key of the iterator
Definition: json.hpp:5114
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
std::input_iterator_tag iterator_category
Definition: json.hpp:5043
string_type array_index_str
a string representation of the array index
Definition: json.hpp:5054
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:5044
IteratorType anchor
the iterator
Definition: json.hpp:5048
proxy class for the items() function
Definition: json.hpp:5158
IteratorType::pointer container
the container to iterate
Definition: json.hpp:5161
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5183
iteration_proxy(iteration_proxy const &)=default
iteration_proxy(iteration_proxy &&) noexcept=default
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:5177
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5167
iteration_proxy & operator=(iteration_proxy const &)=default
Definition: json.hpp:6126
IteratorType end
Definition: json.hpp:6148
bool empty() const
Definition: json.hpp:6153
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:6134
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6130
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6128
IteratorType current
Definition: json.hpp:6147
Definition: json.hpp:14487
json_ref(json_ref &&) noexcept=default
json_ref(const value_type &value)
Definition: json.hpp:14495
json_ref(value_type &&value)
Definition: json.hpp:14491
value_type const & operator*() const
Definition: json.hpp:14526
value_type const * operator->() const
Definition: json.hpp:14531
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:14499
json_ref(Args &&... args)
Definition: json.hpp:14506
value_type moved_or_copied() const
Definition: json.hpp:14517
BasicJsonType value_type
Definition: json.hpp:14489
a template for a reverse iterator class
Definition: json.hpp:13466
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:13482
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:13494
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:13488
std::ptrdiff_t difference_type
Definition: json.hpp:13468
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13506
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13530
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:13536
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:13524
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:13472
reference value() const
return the value of an iterator
Definition: json.hpp:13543
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:13479
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:13500
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:13470
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13518
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:13475
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:13512
Definition: json.hpp:7138
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7141
bool end_object()
Definition: json.hpp:7191
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7181
bool binary(binary_t &)
Definition: json.hpp:7176
bool number_integer(number_integer_t)
Definition: json.hpp:7156
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7196
bool boolean(bool)
Definition: json.hpp:7151
bool null()
Definition: json.hpp:7146
bool end_array()
Definition: json.hpp:7201
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:7161
bool string(string_t &)
Definition: json.hpp:7171
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:7144
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:7166
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:7206
bool key(string_t &)
Definition: json.hpp:7186
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7140
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7142
typename BasicJsonType::string_t string_t
Definition: json.hpp:7143
Definition: json.hpp:6831
bool boolean(bool val)
Definition: json.hpp:6862
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:7019
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:7117
typename BasicJsonType::string_t string_t
Definition: json.hpp:6836
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6880
constexpr bool is_errored() const
Definition: json.hpp:7031
bool string(string_t &val)
Definition: json.hpp:6886
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6834
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6837
bool start_object(std::size_t len)
Definition: json.hpp:6898
bool start_array(std::size_t len)
Definition: json.hpp:6969
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6833
bool end_array()
Definition: json.hpp:6986
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool key(string_t &val)
Definition: json.hpp:6916
bool end_object()
Definition: json.hpp:6933
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.hpp:7053
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6839
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6838
bool null()
Definition: json.hpp:6856
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6874
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6841
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6835
bool number_integer(number_integer_t val)
Definition: json.hpp:6868
bool binary(binary_t &val)
Definition: json.hpp:6892
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6648
json_sax_dom_parser(const json_sax_dom_parser &)=delete
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool string(string_t &val)
Definition: json.hpp:6702
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6661
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6769
bool null()
Definition: json.hpp:6672
typename BasicJsonType::string_t string_t
Definition: json.hpp:6653
bool start_object(std::size_t len)
Definition: json.hpp:6714
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6651
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6690
bool number_integer(number_integer_t val)
Definition: json.hpp:6684
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: json.hpp:6795
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6650
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool binary(binary_t &val)
Definition: json.hpp:6708
json_sax_dom_parser(json_sax_dom_parser &&)=default
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6818
bool boolean(bool val)
Definition: json.hpp:6678
bool end_array()
Definition: json.hpp:6758
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6696
bool end_object()
Definition: json.hpp:6736
constexpr bool is_errored() const
Definition: json.hpp:6781
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6654
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6652
bool start_array(std::size_t len)
Definition: json.hpp:6746
bool key(string_t &val)
Definition: json.hpp:6726
Definition: json.hpp:7253
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:7280
token_type
token types for the parser
Definition: json.hpp:7257
lexical analysis
Definition: json.hpp:7330
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:8538
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8704
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:7387
token_type scan_string()
scan a string literal
Definition: json.hpp:7472
void skip_whitespace()
Definition: json.hpp:8718
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7341
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8691
std::string get_token_string() const
Definition: json.hpp:8666
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7333
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8630
typename BasicJsonType::string_t string_t
Definition: json.hpp:7334
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7332
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition: json.hpp:7435
char_int_type get()
Definition: json.hpp:8555
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8658
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7331
token_type scan()
Definition: json.hpp:8727
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8636
bool scan_comment()
scan a comment
Definition: json.hpp:8062
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:7339
lexer(lexer &&)=default
~lexer()=default
lexer & operator=(lexer &&)=default
lexer(const lexer &)=delete
typename InputAdapterType::char_type char_type
Definition: json.hpp:7335
InputAdapterType ia
input adapter
Definition: json.hpp:8817
lexer & operator=(lexer &)=delete
token_type scan_number()
scan a number literal
Definition: json.hpp:8187
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.hpp:7336
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8648
void add(char_int_type c)
add a character to token_buffer
Definition: json.hpp:8619
void unget()
unget current character (read it again on next get)
Definition: json.hpp:8592
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8642
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:7361
exception indicating other library errors
Definition: json.hpp:4426
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4429
exception indicating access out of the defined range
Definition: json.hpp:4409
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4412
Definition: json.hpp:14704
output_adapter(StringType &s)
Definition: json.hpp:14715
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:14711
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:14707
output adapter for output streams
Definition: json.hpp:14656
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:14658
void write_character(CharType c) override
Definition: json.hpp:14662
std::basic_ostream< CharType > & stream
Definition: json.hpp:14674
output adapter for basic_string
Definition: json.hpp:14681
void write_character(CharType c) override
Definition: json.hpp:14687
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:14683
StringType & str
Definition: json.hpp:14699
output adapter for byte vectors
Definition: json.hpp:14631
std::vector< CharType, AllocatorType > & v
Definition: json.hpp:14649
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:14633
void write_character(CharType c) override
Definition: json.hpp:14637
exception indicating a parse error
Definition: json.hpp:4321
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition: json.hpp:4333
static std::string position_string(const position_t &pos)
Definition: json.hpp:4364
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4341
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4358
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.hpp:4361
syntax analysis
Definition: json.hpp:12038
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:12443
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:12048
typename lexer_t::token_type token_type
Definition: json.hpp:12044
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:12070
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:12040
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:12039
typename BasicJsonType::string_t string_t
Definition: json.hpp:12042
lexer_t m_lexer
the lexer
Definition: json.hpp:12478
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:12130
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:12041
token_type get_token()
get next token from lexer
Definition: json.hpp:12438
Definition: json.hpp:12530
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:12592
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12624
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:12559
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:12605
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:12553
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12575
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:12565
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:12598
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12618
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12570
constexpr difference_type get_value() const noexcept
Definition: json.hpp:12541
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12587
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:12580
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:12547
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12611
std::ptrdiff_t difference_type
Definition: json.hpp:12532
Definition: json.hpp:17727
typename BasicJsonType::binary_t::value_type binary_char_t
Definition: json.hpp:17732
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:17731
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:17742
serializer & operator=(const serializer &)=delete
~serializer()=default
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:18659
string_t indent_string
the indentation string
Definition: json.hpp:18656
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:17730
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:17729
serializer & operator=(serializer &&)=delete
typename BasicJsonType::string_t string_t
Definition: json.hpp:17728
const char indent_char
the indentation character
Definition: json.hpp:18654
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:17782
serializer(const serializer &)=delete
serializer(serializer &&)=delete
Definition: json.hpp:6452
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6460
contiguous_bytes_input_adapter ia
Definition: json.hpp:6476
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6467
contiguous_bytes_input_adapter && get()
Definition: json.hpp:6470
exception indicating executing a member function with a wrong type
Definition: json.hpp:4392
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4395
Definition: json.hpp:6286
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6293
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition: json.hpp:6320
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition: json.hpp:6325
BaseInputAdapter base_adapter
Definition: json.hpp:6311
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6290
char char_type
Definition: json.hpp:6288
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition: json.hpp:6323
void fill_buffer()
Definition: json.hpp:6314
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:13596
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:13982
json_pointer< string_t > convert() const &
Definition: json.hpp:14395
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:13691
static BasicJsonType::size_type array_index(const string_t &s)
Definition: json.hpp:13774
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:13618
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:13698
result reference_tokens
Definition: json.hpp:13820
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:13622
static std::vector< string_t > split(const string_t &reference_string)
split the string input to reference tokens
Definition: json.hpp:14226
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:13757
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:13834
void pop_back()
remove last reference token
Definition: json.hpp:13719
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:13628
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:13676
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13750
json_pointer< string_t > convert() &&
Definition: json.hpp:14402
std::vector< string_t > reference_tokens
the reference tokens
Definition: json.hpp:14442
return result
Definition: json.hpp:13821
static void flatten(const string_t &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:14295
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13658
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:13683
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:13914
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13705
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:14367
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:13668
const string_t & back() const
return last reference token
Definition: json.hpp:13731
friend std::ostream & operator<<(std::ostream &o, const json_pointer &ptr)
write string representation of the JSON pointer to stream
Definition: json.hpp:13649
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:14040
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13743
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:14089
bool contains(const BasicJsonType *ptr) const
Definition: json.hpp:14138
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:5231
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2565
#define JSON_HEDLEY_CONST
Definition: json.hpp:1795
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1079
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2468
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1425
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2528
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:71
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1690
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1583
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2495
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:24041
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2024
#define JSON_CATCH(exception)
Definition: json.hpp:2494
#define JSON_ASSERT(x)
Definition: json.hpp:2521
#define JSON_THROW(exception)
Definition: json.hpp:2492
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:78
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:69
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2574
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1691
#define JSON_TRY
Definition: json.hpp:2493
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:124
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2474
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:70
bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition: json.hpp:14447
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2749
bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition: json.hpp:14454
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:116
basic_json<> json
default specialization
Definition: json.hpp:3378
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1080
#define JSON_EXPLICIT
Definition: json.hpp:2786
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1373
#define JSON_HEDLEY_PURE
Definition: json.hpp:1764
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:22490
indent
Definition: convert.py:38
f
Definition: convert.py:38
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:17066
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:16902
Target reinterpret_bits(const Source source)
Definition: json.hpp:16622
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:16763
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:17120
constexpr int kAlpha
Definition: json.hpp:16885
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition: json.hpp:17462
constexpr int kGamma
Definition: json.hpp:16886
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:17161
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:17502
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:17554
detail namespace with internal helper functions
Definition: json.hpp:226
input_format_t
the supported input formats
Definition: json.hpp:6020
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5625
static void unescape(StringType &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2968
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:286
typename make_void< Ts... >::type void_t
Definition: json.hpp:232
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:8920
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:14626
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:4125
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:8928
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12029
OutStringType concat(Args &&... args)
Definition: json.hpp:4199
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4134
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3473
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3479
typename std::conditional< is_usable_as_key_type< typename BasicJsonType::object_comparator_t, typename BasicJsonType::object_t::key_type, KeyTypeCVRef, RequireTransparentComparator, ExcludeObjectKeyType >::value &&!is_json_iterator_of< BasicJsonType, KeyType >::value, std::true_type, std::false_type >::type is_usable_as_basic_json_key_type
Definition: json.hpp:3917
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:17639
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:5619
typename T::pointer pointer_t
Definition: json.hpp:3464
parse_event_t
Definition: json.hpp:12012
@ value
the parser finished reading a JSON value
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4128
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition: json.hpp:4861
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:3099
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4672
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3145
typename T::value_type value_type_t
Definition: json.hpp:3458
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:290
T conditional_static_cast(U value)
Definition: json.hpp:3951
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4140
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3057
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:4920
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8889
typename T::mapped_type mapped_type_t
Definition: json.hpp:3452
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2934
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:8897
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3645
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5193
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9031
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:283
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3476
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6425
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3153
void concat_into(OutStringType &)
Definition: json.hpp:4115
typename T::key_type key_type_t
Definition: json.hpp:3455
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4052
value_t
the JSON type enumeration
Definition: json.hpp:2836
@ null
null value
@ number_integer
number value (signed integer)
@ boolean
boolean value
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ string
string value
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition: json.hpp:3974
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8905
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)> >, index_sequence< Idx... >)
Definition: json.hpp:4755
static bool little_endianness(int num=1) noexcept
determine system byte order
Definition: json.hpp:9044
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:277
typename std::conditional< is_comparable< Comparator, ObjectKeyType, KeyTypeCVRef >::value &&!(ExcludeObjectKeyType &&std::is_same< KeyType, ObjectKeyType >::value) &&(!RequireTransparentComparator||is_detected< detect_is_transparent, Comparator >::value) &&!is_json_pointer< KeyType >::value, std::true_type, std::false_type >::type is_usable_as_key_type
Definition: json.hpp:3901
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5867
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:4131
typename T::iterator_category iterator_category_t
Definition: json.hpp:3470
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5849
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:2865
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6368
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:8923
typename std::conditional< is_detected< detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType >::value, std::true_type, std::false_type >::type has_erase_with_key_type
Definition: json.hpp:3929
error_handler_t
how to treat decoding errors
Definition: json.hpp:17719
@ strict
throw a type_error exception in case of invalid UTF-8
@ replace
replace invalid UTF-8 sequences with U+FFFD
std::size_t concat_length()
Definition: json.hpp:4084
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition: json.hpp:3648
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4515
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3552
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:4119
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5493
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4529
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8881
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3161
typename T::difference_type difference_type_t
Definition: json.hpp:3461
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3043
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4855
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3887
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8901
typename T::reference reference_t
Definition: json.hpp:3467
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8885
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:8916
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:3920
typename T::key_compare detect_key_compare
Definition: json.hpp:3536
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8909
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:4137
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8893
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:271
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2953
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:5030
std::integral_constant< bool,(std::is_signed< OfType >::value &&(sizeof(T)< sizeof(OfType)))||(same_sign< OfType, T >::value &&sizeof(OfType)==sizeof(T)) > never_out_of_range
Definition: json.hpp:3979
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4122
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:8913
Definition: json.hpp:24047
name
Definition: setup.py:6
Definition: json.hpp:5214
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24114
namespace for Niels Lohmann
Definition: json.hpp:5678
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:5702
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:5692
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:5682
Definition: json.hpp:3544
typename BasicJsonType::object_t object_t
Definition: json.hpp:3545
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3546
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3548
Definition: json.hpp:3560
Definition: json.hpp:3559
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: json.hpp:6391
Definition: json.hpp:258
std::false_type value_t
Definition: json.hpp:259
Default type
Definition: json.hpp:260
Definition: json.hpp:16750
diyfp w
Definition: json.hpp:16751
diyfp minus
Definition: json.hpp:16752
diyfp plus
Definition: json.hpp:16753
Definition: json.hpp:16889
std::uint64_t f
Definition: json.hpp:16890
int e
Definition: json.hpp:16891
int k
Definition: json.hpp:16892
Definition: json.hpp:16632
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:16656
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:16738
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:16721
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:16644
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:16638
std::uint64_t f
Definition: json.hpp:16635
int e
Definition: json.hpp:16636
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5418
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5393
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5383
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5405
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5434
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5322
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5331
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5276
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5344
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5370
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5357
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5453
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5474
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5463
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5298
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5309
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5289
Definition: json.hpp:5270
Definition: json.hpp:4950
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:4952
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3498
Definition: json.hpp:3483
Definition: json.hpp:3539
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3513
Definition: json.hpp:3508
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3528
Definition: json.hpp:3523
Definition: json.hpp:4466
Definition: json.hpp:3085
T value_type
Definition: json.hpp:3086
static constexpr std::size_t size() noexcept
Definition: json.hpp:3087
an iterator value
Definition: json.hpp:12646
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12650
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12652
Definition: json.hpp:3432
Definition: json.hpp:3419
Definition: json.hpp:3878
Definition: json.hpp:3742
Definition: json.hpp:3761
Definition: json.hpp:3832
Definition: json.hpp:3682
Definition: json.hpp:3719
static constexpr auto value
Definition: json.hpp:3720
Definition: json.hpp:3835
Definition: json.hpp:3848
Definition: json.hpp:3655
Definition: json.hpp:3805
Definition: json.hpp:3715
Definition: json.hpp:3726
ConstructibleStringType laundered_type
Definition: json.hpp:3731
static constexpr auto value
Definition: json.hpp:3734
Definition: json.hpp:3851
Definition: json.hpp:3592
Definition: json.hpp:3572
Definition: json.hpp:274
Definition: json.hpp:3491
static constexpr bool value
Definition: json.hpp:3492
Definition: json.hpp:6344
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6345
Definition: json.hpp:3608
Definition: json.hpp:3857
Definition: json.hpp:3442
Definition: json.hpp:3939
char x[2]
Definition: json.hpp:3940
Definition: json.hpp:3935
static one test(decltype(&C::capacity))
@ value
Definition: json.hpp:3946
char one
Definition: json.hpp:3936
static two test(...)
Definition: json.hpp:3627
detected_t< result_of_end, t_ref > sentinel
Definition: json.hpp:3632
detected_t< result_of_begin, t_ref > iterator
Definition: json.hpp:3631
typename std::add_lvalue_reference< T >::type t_ref
Definition: json.hpp:3629
static constexpr bool value
Definition: json.hpp:3641
static constexpr auto is_iterator_begin
Definition: json.hpp:3637
Definition: json.hpp:8963
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8968
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8969
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8972
typename BasicJsonType::exception exception_t
Definition: json.hpp:8973
typename BasicJsonType::string_t string_t
Definition: json.hpp:8971
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8970
Definition: json.hpp:8932
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8941
typename BasicJsonType::exception exception_t
Definition: json.hpp:8942
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8939
typename BasicJsonType::string_t string_t
Definition: json.hpp:8940
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8938
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8937
Definition: json.hpp:3868
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6356
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6360
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6334
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6333
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6336
IteratorType iterator_type
Definition: json.hpp:6332
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3260
Definition: json.hpp:3248
Definition: json.hpp:3229
Definition: json.hpp:229
void type
Definition: json.hpp:230
Definition: json.hpp:3566
Definition: json.hpp:244
nonesuch(nonesuch const &&)=delete
~nonesuch()=delete
void operator=(nonesuch &&)=delete
void operator=(nonesuch const &)=delete
nonesuch(nonesuch const &)=delete
abstract output adapter interface
Definition: json.hpp:14612
output_adapter_protocol(const output_adapter_protocol &)=default
virtual ~output_adapter_protocol()=default
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
virtual void write_characters(const CharType *s, std::size_t length)=0
struct to capture the start position of the current token
Definition: json.hpp:2999
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:3003
std::size_t lines_read
the number of lines read
Definition: json.hpp:3005
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3001
Definition: json.hpp:3169
Definition: json.hpp:3168
Definition: json.hpp:3174
static constexpr T value
Definition: json.hpp:3175
Definition: json.hpp:5645
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:5647
Definition: json.hpp:3105
Definition: json.hpp:3124
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3126
static constexpr bool test(T val)
Definition: json.hpp:4036
static constexpr bool test(T)
Definition: json.hpp:4045
Definition: json.hpp:4031
static constexpr bool test(T val)
Definition: json.hpp:3989
static constexpr bool test(T val)
Definition: json.hpp:4009
static constexpr bool test(T val)
Definition: json.hpp:3999
static constexpr bool test(T val)
Definition: json.hpp:4020
Definition: json.hpp:3984
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:6225
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:6167
Definition: json.hpp:6161
Definition: json.hpp:13606
T type
Definition: json.hpp:13607
SAX interface.
Definition: json.hpp:6517
virtual bool binary(binary_t &val)=0
a binary value was read
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
virtual bool key(string_t &val)=0
an object key was read
json_sax()=default
virtual bool string(string_t &val)=0
a string value was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6518
typename BasicJsonType::string_t string_t
Definition: json.hpp:6521
virtual bool end_array()=0
the end of an array was read
json_sax(const json_sax &)=default
virtual bool boolean(bool val)=0
a boolean value was read
virtual bool end_object()=0
the end of an object was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6520
virtual bool null()=0
a null value was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6519
json_sax(json_sax &&) noexcept=default
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6522
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
a minimal map-like container that preserves insertion order
Definition: json.hpp:18701
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:18704
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:18995
typename Container::value_type value_type
Definition: json.hpp:18708
std::equal_to< Key > key_compare
Definition: json.hpp:18712
iterator erase(iterator pos)
Definition: json.hpp:18873
T mapped_type
Definition: json.hpp:18703
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:18718
T & operator[](KeyType &&key)
Definition: json.hpp:18760
typename Container::iterator iterator
Definition: json.hpp:18705
const T & at(KeyType &&key) const
Definition: json.hpp:18820
T & at(KeyType &&key)
Definition: json.hpp:18792
const T & operator[](KeyType &&key) const
Definition: json.hpp:18772
iterator find(const key_type &key)
Definition: json.hpp:18957
iterator erase(iterator first, iterator last)
Definition: json.hpp:18878
const T & at(const key_type &key) const
Definition: json.hpp:18805
const_iterator find(const key_type &key) const
Definition: json.hpp:18983
T & operator[](const key_type &key)
Definition: json.hpp:18753
size_type erase(KeyType &&key)
Definition: json.hpp:18854
typename Container::size_type size_type
Definition: json.hpp:18707
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:18717
void insert(InputIt first, InputIt last)
Definition: json.hpp:19018
size_type count(const key_type &key) const
Definition: json.hpp:18931
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:18740
size_type erase(const key_type &key)
Definition: json.hpp:18833
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:18722
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:19000
size_type count(KeyType &&key) const
Definition: json.hpp:18945
Key key_type
Definition: json.hpp:18702
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:18720
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:19015
const T & operator[](const key_type &key) const
Definition: json.hpp:18765
iterator find(KeyType &&key)
Definition: json.hpp:18971
T & at(const key_type &key)
Definition: json.hpp:18777
typename Container::const_iterator const_iterator
Definition: json.hpp:18706
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:18725
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:24083
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:24097